EntityManager find with pessimistic lock does not check for transaction when cached #5885

Closed
opened 2026-01-22 15:21:13 +01:00 by admin · 4 comments
Owner

Originally created by @madwizard-thomas on GitHub (Feb 15, 2018).

Originally assigned to: @Majkl578, @Ocramius on GitHub.

When a pessimistic lock mode is passed to EntityManager::find it normally throws a TransactionRequiredException if no transaction is currently active.

However if the entity is currently in the identity map, it will refresh the entity from the database and return it but not check if a transaction is running. The refresh query has 'FOR UPDATE' (in case of pessimistic write) but this has no effect since there is no transaction.

To reproduce:

// $em is EntityManager, Order entity can be any entity
$em->find(Order::class, 1); // Load order id 1 in entity map
$em->find(Order::class, 1, LockMode::PESSIMISTIC_WRITE); // does not throw exception
$em->find(Order::class, 2, LockMode::PESSIMISTIC_WRITE); // throws TransactionRequiredException 

Tested with doctrine 2.5.14 but latest code seems to have the same issue.

Originally created by @madwizard-thomas on GitHub (Feb 15, 2018). Originally assigned to: @Majkl578, @Ocramius on GitHub. When a pessimistic lock mode is passed to EntityManager::find it normally throws a TransactionRequiredException if no transaction is currently active. However if the entity is currently in the identity map, it will refresh the entity from the database and return it but not check if a transaction is running. The refresh query has 'FOR UPDATE' (in case of pessimistic write) but this has no effect since there is no transaction. To reproduce: ```php // $em is EntityManager, Order entity can be any entity $em->find(Order::class, 1); // Load order id 1 in entity map $em->find(Order::class, 1, LockMode::PESSIMISTIC_WRITE); // does not throw exception $em->find(Order::class, 2, LockMode::PESSIMISTIC_WRITE); // throws TransactionRequiredException ``` Tested with doctrine 2.5.14 but latest code seems to have the same issue.
admin added the Bug label 2026-01-22 15:21:13 +01:00
admin closed this issue 2026-01-22 15:21:13 +01:00
Author
Owner

@Ocramius commented on GitHub (Feb 15, 2018):

Is this a MySQL specific problem?

On 15 Feb 2018 20:22, "Thomas" notifications@github.com wrote:

When a pessimistic lock mode is passed to EntityManager::find it normally
throws a TransactionRequiredException if no transaction is currently active.

However if the entity is currently in the identity map, it will refresh
the entity from the database and return it but not check if a transaction
is running. The refresh query has 'FOR UPDATE' (in case of pessimistic
write) but this has no effect since there is no transaction.

To reproduce:

// $em is EntityManager, Order entity can be any entity$em->find(Order::class, 1); // Load order id 1 in entity map$em->find(Order::class, 1, LockMode::PESSIMISTIC_WRITE); // does not throw exception$em->find(Order::class, 2, LockMode::PESSIMISTIC_WRITE); // throws TransactionRequiredException

Tested with doctrine 2.5.14 but latest code seems to have the same issue.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/doctrine/doctrine2/issues/7068, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJakE3-bN0Buoz3ONz6xqcPX3zccpbKks5tVIPlgaJpZM4SHXqb
.

@Ocramius commented on GitHub (Feb 15, 2018): Is this a MySQL specific problem? On 15 Feb 2018 20:22, "Thomas" <notifications@github.com> wrote: > When a pessimistic lock mode is passed to EntityManager::find it normally > throws a TransactionRequiredException if no transaction is currently active. > > However if the entity is currently in the identity map, it will refresh > the entity from the database and return it but not check if a transaction > is running. The refresh query has 'FOR UPDATE' (in case of pessimistic > write) but this has no effect since there is no transaction. > > To reproduce: > > // $em is EntityManager, Order entity can be any entity$em->find(Order::class, 1); // Load order id 1 in entity map$em->find(Order::class, 1, LockMode::PESSIMISTIC_WRITE); // does not throw exception$em->find(Order::class, 2, LockMode::PESSIMISTIC_WRITE); // throws TransactionRequiredException > > Tested with doctrine 2.5.14 but latest code seems to have the same issue. > > — > You are receiving this because you are subscribed to this thread. > Reply to this email directly, view it on GitHub > <https://github.com/doctrine/doctrine2/issues/7068>, or mute the thread > <https://github.com/notifications/unsubscribe-auth/AAJakE3-bN0Buoz3ONz6xqcPX3zccpbKks5tVIPlgaJpZM4SHXqb> > . >
Author
Owner

@madwizard-thomas commented on GitHub (Feb 15, 2018):

I don't think so, but have only tested it with MySQL. It seems to be caused by the early return statement here before the transaction check here

@madwizard-thomas commented on GitHub (Feb 15, 2018): I don't think so, but have only tested it with MySQL. It seems to be caused by the early return statement [here](https://github.com/doctrine/doctrine2/blob/v2.5.14/lib/Doctrine/ORM/EntityManager.php#L435) before the transaction check [here](https://github.com/doctrine/doctrine2/blob/v2.5.14/lib/Doctrine/ORM/EntityManager.php#L455)
Author
Owner

@BreiteSeite commented on GitHub (Feb 17, 2018):

Thanks @madwizard-thomas for the minimal code to reproduce. Helped a lot.

@Ocramius i added this as a test for the test-suite and also provided a fix in #7075

@BreiteSeite commented on GitHub (Feb 17, 2018): Thanks @madwizard-thomas for the minimal code to reproduce. Helped a lot. @Ocramius i added this as a test for the test-suite and also provided a fix in #7075
Author
Owner

@Ocramius commented on GitHub (Jul 3, 2018):

Handled in #7075 and #7291

@Ocramius commented on GitHub (Jul 3, 2018): Handled in #7075 and #7291
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5885