doctrine / orm

Doctrine Object Relational Mapper (ORM)
https://www.doctrine-project.org/projects/orm.html
MIT License
9.92k stars 2.51k forks source link

[Docs] Explicit transaction example with connection does not close EntityManager at rollback #10886

Open ToshY opened 1 year ago

ToshY commented 1 year ago

Bug Report

Q A
BC Break no
Version >=2.5.0

Summary

Current behavior

<?php
// $em instanceof EntityManager
$em->getConnection()->beginTransaction(); // suspend auto-commit
try {
    //... do some work
    $user = new User;
    $user->setName('George');
    $em->persist($user);
    $em->flush();
    $em->getConnection()->commit();
} catch (Exception $e) {
    $em->getConnection()->rollback();
    throw $e;
}

Expected behavior

<?php
// $em instanceof EntityManager
$em->getConnection()->beginTransaction(); // suspend auto-commit
try {
    //... do some work
    $user = new User;
    $user->setName('George');
    $em->persist($user);
    $em->flush();
    $em->getConnection()->commit();
} catch (Exception $e) {
    $em->close();
    $em->getConnection()->rollback();
    throw $e;
}
mpdude commented 1 year ago

What about this code?

https://github.com/doctrine/orm/blob/597a63a86ca8c5f9d1ec2dc74fe3d1269d43434a/lib/Doctrine/ORM/UnitOfWork.php#L477-L487

When an exception occurs inside UnitOfWork::commit(), the EM is closed before the exception is re-thrown. Isn't that what you're looking for?

ToshY commented 1 year ago

@mpdude I don't think we are on the same page.

As it's currently not "funcionally equivalent", I propose to update the documentation to include $em->close() in the catch block before the rollback, in order to be consistent with the behavior of EntityManager#transactional as mentioned in the text.

mpdude commented 1 year ago

Doesn't the UoW already close the entity manager when an exception is thrown from inside UoW::commit()?

mpdude commented 1 year ago

What I want to say is:

From the user's perspective, you don't have to close the EntityManager, in neither of the two ways. The ORM code will make sure it will be closed.