Here’s a complete solution covering all three aspects of handling concurrent updates:
Optimistic Concurrency Control:
Windchill’s REST API uses ETags to implement optimistic locking. The proper update flow is:
// Pseudocode - ETag-based update flow:
1. GET /documents/{id} - Receive ETag in response header
2. Extract ETag value from response
3. Apply metadata changes to document object
4. PUT /documents/{id} with If-Match: {ETag} header
5. If 409 conflict: goto step 1 (with backoff delay)
6. If 200 success: update complete
Implement a maximum retry count (3-5 attempts) to prevent infinite loops. Use exponential backoff: 1s, 2s, 4s between retries.
ETag/Version Headers:
Always include version headers in your API requests:
- If-Match: Use for updates - ensures you’re modifying the expected version
- If-None-Match: Use for conditional GETs - avoids fetching unchanged documents
- If-Modified-Since: Useful for polling scenarios to reduce bandwidth
Example headers:
GET /documents/12345
Response: ETag: "v1.2.45"
PUT /documents/12345
If-Match: "v1.2.45"
Content-Type: application/json
The ETag format varies but typically includes version iteration. Never parse or construct ETags manually - treat them as opaque tokens.
Conflict Resolution Strategies:
Implement intelligent conflict handling based on your business requirements:
- Last-Write-Wins: Simple retry with fresh data (acceptable for low-value metadata)
- Merge Strategy: Fetch latest, intelligently merge your changes, retry update
- User Notification: For critical conflicts, notify users and require manual resolution
- Field-Level Locking: Use PATCH for granular updates, reducing conflict surface
For your scenario with external workflow triggers, implement merge logic:
// Pseudocode - Conflict resolution with merge:
1. Attempt initial update with cached ETag
2. On 409 conflict:
a. GET latest document state
b. Compare your changes vs current state
c. Apply merge rules:
- Status changes: external system wins
- Owner changes: preserve if changed by user
- Custom attrs: merge if non-overlapping
d. Retry update with new ETag
3. Log all conflicts for audit trail
For high-contention documents, implement a queuing mechanism in your external system. Serialize updates to the same document using a distributed lock (Redis, database advisory locks) or message queue. This prevents multiple processes from competing for the same document.
Monitor 409 error rates to identify hot-spot documents that need architectural changes - perhaps splitting metadata across multiple objects or implementing a different update pattern like event-based eventual consistency.
Implement comprehensive logging: record ETag values, retry attempts, merge decisions, and final outcomes. This audit trail is crucial for troubleshooting sync inconsistencies and understanding concurrent access patterns in your integration.