doctrinesymfony

How should flushing be handled in a doctrine EntityManager instance shared across different services in symfony2?


I have defined several services in symfony 2 which persist changes to the database. These services have the doctrine instance as one of their dependencies:

a.given.service:
    class: Acme\TestBundle\Service\AGivenService
    arguments: [@doctrine]

If I have two different services and both of them persist objects through the EntityManager, which is obtained like this from the doctrine instance:

$em = $doctrine->getEntityManager();

Would all services always share the same EntityManager? If so, how should I handle flushing if I wanted to handle all the changes in a single transaction? I have checked this: http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/transactions-and-concurrency.html and it explains how to handle different transactions in a request, but what I want to achieve is having different changes in different services handled as a single transaction.

Is there a better approach to handle multiple changes in different services?

For now my best bet is having a front-end service in charge of calling the other services and doing the flushing afterwards. Backend services would persist objects but would not do any flushing.


Solution

  • The docs you quoted are exactly what you want:

    $em->getConnection()->beginTransaction();
    try{
      $service1 = $this->get('myservice1');
      $service1->doSomething();
    
      $service2 = $this->get('myservice2');
      $service2->doSomething();
    
      $em->getConnection()->commit();
    catch(\Exception $e){
      $em->getConnection()->rollback();
    }
    

    If your $em is the same as the one in your container, i.e. you are only using one entity manager, you are now able to flush inside your services and roll back if an error occurs.