mirror of
https://github.com/doctrine/orm.git
synced 2026-03-23 22:42:18 +01:00
ManyToMany UniqueConstraintViolationException (race condition) #6161
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Cosmologist on GitHub (Jan 23, 2019).
Originally assigned to: @Ocramius on GitHub.
A race condition when two parallel processes try to create a relationship (for ManyToMany association and join table).
If each process decides to create a new relationship entry in the join table, the first process will create a record, and the second process will receive the exception UniqueConstraintViolationException - this is logical, but this is a standard situation.
ManyToManyPersister::getInsertRowSql - if each process decides to create a new relationship entry in the join table, then the first process will create an entry and second process will receive the exception UniqueConstraintViolationException.
At the low level - it is should cause an error, but at the application level, this is not a problem if the necessary relationship already exists.
Maybe to use
INSERT IGNOREstatement or another platform depended/independend solution?@Ocramius commented on GitHub (Jan 23, 2019):
I'd say that an exception is the correct behavior there: idempotent operations are not the wished default behavior for
INSERT.@Cosmologist commented on GitHub (Jan 23, 2019):
Of course. But I don’t have the ability to properly handle this, because the entity manager has been closed. I know about Registry :: resetEntityManager, but the application state will be lost. I can try again (how many attempts should be?), If possible. Or show the stupid message "Please try again" if this is a request from the UI.
@Ocramius commented on GitHub (Jan 24, 2019):
Yeah, transaction failures will lead to hard ORM crashes - no way around that, since the ORM isn't capable of understanding which statements failed, and if the application state can be rolled back at all (it won't revert any state anyway)