Skip to content

Handle race conditions #5

Open
Open

Description

@loevgaard

In the DoctrineOrmBasedMetadataPersister there is a race condition, both when inserting and updating.

Right now the inserting is handled by catching the exception, which doesn't really handle the problem.

When updating the metadata, it's the one that updates the last that wins. This could be handled with optimistic locking.

Activity

  1. loevgaard commented on Oct 26, 2026

    @loevgaard
    MemberAuthor

    Details from the functional tests in #13, which simulate the insert race (MetadataTest::it_keeps_the_row_of_a_concurrent_request_that_stored_it_first):

    • The request that loses the race silently loses its metadata: the row keeps what the other request stored.
    • Catching UniqueConstraintViolationException after flush() doesn't make the request whole again, because the ORM has already closed the entity manager by then. $entityManager->isOpen() is false after such a request. Anything that uses the entity manager after kernel.finish_request in the same request (for example a kernel.terminate listener) gets EntityManagerClosed.
    • An INSERT that fails for another reason isn't caught at all, see A client id longer than 255 characters makes requests that write metadata fail on MySQL and PostgreSQL #17.

    Writing the row with DBAL instead of flush(), as suggested in #16, would leave the entity manager open on a unique violation. The persister could then also retry: UPDATE, INSERT, and on a unique violation UPDATE again. That keeps the losing request's metadata, but for concurrent updates the last write still wins, so the optimistic locking mentioned above would still be needed for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions