ManyToMany UniqueConstraintViolationException (race condition) #6161

Closed
opened 2026-01-22 15:28:01 +01:00 by admin · 3 comments
Owner

Originally created by @Cosmologist on GitHub (Jan 23, 2019).

Originally assigned to: @Ocramius on GitHub.

Q A
Version 2.5.4

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 IGNORE statement or another platform depended/independend solution?

Originally created by @Cosmologist on GitHub (Jan 23, 2019). Originally assigned to: @Ocramius on GitHub. | Q | A |------------ | ----- | Version | 2.5.4 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](https://github.com/doctrine/orm/blob/master/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php#L564) - 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 IGNORE``` statement or another platform depended/independend solution?
admin added the Can't FixQuestion labels 2026-01-22 15:28:01 +01:00
admin closed this issue 2026-01-22 15:28:01 +01:00
Author
Owner

@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.

@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`.
Author
Owner

@Cosmologist 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.

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.

@Cosmologist 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`. 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.
Author
Owner

@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)

@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)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6161