transactional() helper and closed entityManager #5185

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

Originally created by @Anyqax on GitHub (Jul 11, 2016).

Originally assigned to: @Ocramius on GitHub.

Currently, using the transactional helper, any exception that is thrown leads to the entityManager being closed. Therefore it is impossible to use this construct and save the exception to a database log. Wouldn't it be sufficient if the entityManager was only closed on an ORMException instead of an \Exception?

Originally created by @Anyqax on GitHub (Jul 11, 2016). Originally assigned to: @Ocramius on GitHub. Currently, using the transactional helper, any exception that is thrown leads to the entityManager being closed. Therefore it is impossible to use this construct and save the exception to a database log. Wouldn't it be sufficient if the entityManager was only closed on an ORMException instead of an \Exception?
admin added the BugCan't Fix labels 2026-01-22 15:00:57 +01:00
admin closed this issue 2026-01-22 15:00:57 +01:00
Author
Owner

@Ocramius commented on GitHub (Jul 11, 2016):

Therefore it is impossible to use this construct and save the exception to a database log

An exception triggered during transactional() execution basically means that something went wrong (maybe DB-side, that may also happen), and that the entire entity graph that you are working with may be corrupted (due to transaction boundaries being broken). Therefore, your in-memory state and your db state are out of sync, and the ORM must be made inaccessible.

We can't limit this behavior to a small set of ORM exceptions, because we don't know what layers/adapters are below it (in DBAL or even in DBAL drivers, which may be implemented in custom ways).

@Ocramius commented on GitHub (Jul 11, 2016): `Therefore it is impossible to use this construct and save the exception to a database log` An exception triggered during `transactional()` execution basically means that something went wrong (maybe DB-side, that may also happen), and that the entire entity graph that you are working with may be corrupted (due to transaction boundaries being broken). Therefore, your in-memory state and your db state are out of sync, and the ORM must be made inaccessible. We can't limit this behavior to a small set of ORM exceptions, because we don't know what layers/adapters are below it (in DBAL or even in DBAL drivers, which may be implemented in custom ways).
Author
Owner

@dewos commented on GitHub (Nov 26, 2017):

Hi @Ocramius, sorry for coming back to this after so long, but I need to understand the internal of the closing em issue.

With a "plain" doctrine configuration/driver is it safe to assume that the uow is still 100% valid with not-db related exceptions?

Most of the time in transactional() the exception is thrown before the persist/commit/flush for other reasons, also, so just the TRANS is started.

Thank you for your time.

@dewos commented on GitHub (Nov 26, 2017): Hi @Ocramius, sorry for coming back to this after so long, but I need to understand the internal of the closing em issue. With a "plain" doctrine configuration/driver is it safe to assume that the uow is still 100% valid with not-db related exceptions? Most of the time in transactional() the exception is thrown before the persist/commit/flush for other reasons, also, so just the TRANS is started. Thank you for your time.
Author
Owner

@lcobucci commented on GitHub (Nov 26, 2017):

With a "plain" doctrine configuration/driver is it safe to assume that the uow is still 100% valid with not-db related exceptions?

Most of the time in transactional() the exception is thrown before the persist/commit/flush for other reasons, also, so just the TRANS is started.

@dewos it's not safe to assume that the UoW will be valid even having non-db related exceptions, because one might have already added some items to be persisted before of throwing any exception. Since the ORM doesn't have control over users' actions it cannot assume anything.

Also, EntityManager#transactional() is essentially a generic helper, if your use case is different than that you shouldn't not use it.

@lcobucci commented on GitHub (Nov 26, 2017): > With a "plain" doctrine configuration/driver is it safe to assume that the uow is still 100% valid with not-db related exceptions? > > Most of the time in transactional() the exception is thrown before the persist/commit/flush for other reasons, also, so just the TRANS is started. @dewos it's not safe to assume that the UoW will be valid even having non-db related exceptions, because one might have already added some items to be persisted before of throwing any exception. Since the ORM doesn't have control over users' actions it cannot assume anything. Also, `EntityManager#transactional()` is essentially a generic helper, if your use case is different than that you shouldn't not use it.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5185