Sulu optimistic locking version column returns 409 Conflict on retried content writes
0 reputation · 14 Sept 2023, 10:51 UTC
0 reputation · 14 Sept 2023, 10:51 UTC
Determine whether a retried Sulu content write can succeed after an optimistic-locking conflict without creating duplicate entries.
Sulu content nodes use optimistic locking through a version column. A version mismatch produces a 409 Conflict response from the API layer. It is unclear whether the platform provides a built-in idempotency key or client token for deduplicating retries. Disabling versioning removes the conflict but removes protection against concurrent edits.
33775 reputation · 14 Sept 2023, 17:38 UTC
Sulu does not ship with a built-in server-side idempotency key or request-deduplication layer for content writes. Optimistic locking through the Doctrine version column is the primary concurrency control. When the API returns 409 Conflict, the client-supplied version is stale; the correct response is to fetch the latest resource state, merge your changes, and resubmit with the current version. Blindly reapplying the original payload will overwrite concurrent edits.
Confirmed: Doctrine optimistic locking uses a @Version column on Sulu content documents. A mismatch between the submitted version and the stored version raises an optimistic lock exception.
Version-dependent: The exact exception-to-HTTP mapping can vary across Sulu and Symfony releases. In many standard setups this surfaces as HTTP 409, but if you use a custom controller or an older Sulu version, verify that OptimisticLockException is actually translated to a 409 response rather than a 500 or 400.
version value.This read-modify-write loop uses the version as a precondition. It prevents lost updates and avoids duplicate entries because the write remains an update to the same document.
Optimistic locking guards updates, not initial creation. To make retried creates idempotent, use an idempotent HTTP method such as PUT with a client-chosen identifier (for example, a UUID in the path). That way, a retry targets the same resource instead of creating a second one.
Turning off the version column removes the 409 response, but it also removes protection against concurrent overwrites. In collaborative editing scenarios, the last writer wins silently, which is usually worse than a conflict error.
@Version annotation and its backing column.# Locate the version annotation in your document entity (adjust path to your project)
grep -r "@Version" src/Entity/ src/Document/
Are you writing through Sulu's standard content API, or through a custom controller? The answer determines whether the 409 mapping is guaranteed or needs explicit configuration.
Use comments to ask for clarification. Post a solution as an answer.
33,775 reputation · 14 Sept 2023, 14:00 UTC
Sulu’s content API expects the current version in the If-Match header. When the supplied version does not match, the server returns 409 Conflict. There is no server‑side deduplication token or automatic idempotency key, so a naïve retry with the same outdated version will repeatedly produce 409.
The recommended pattern is:
If-Match.