Symfony的。使用具有2个以上存储库的事务

时间:2017-08-09 11:32:40

标签: symfony doctrine-orm

在某个控制器中,我需要在数据库中进行多次插入/更新。我正在使用4个实体的4个存储库,但我需要在一个工作单元中完成。

我知道我可以直接在控制器上执行这些插入/更新,并使用$em->getConnection()->beginTransaction()$em->getConnection()->rollBack()$em->getConnection()->commit()来确保完成所有操作或不执行任何操作。但这违反了symfony最佳实践,因此我想使用存储库。

我已经看到了this tutorial的Doctrine 1,但它似乎是一个非常复杂的解决方案,应该更简单。

有什么想法吗?

提前谢谢。

编辑,我正在使用Symfony 3.3.5。

edit2,我添加了一个我想做的例子。整个过程是将一个工人写的消息添加到公司内部的其他部门伙伴。该消息可能有也可能没有附件(让我们说它有)。这些文件应显示为部门和公司文件,这样即使删除了部门,文件也会继续显示为属于公司。

我没有在代码中包含错误处理以使其更简单。

// New Files
$file1 = new File(); // AppBundle\Entity\File
$file1->setName("name1");
$file2 = new File();
$file2->setName("name2");

$em->getRepository('AppBundle:File')->insert($file1);
$em->getRepository('AppBundle:File')->insert($file2);

// New Post
$post = new Post(); // AppBundle\Entity\Post
$post->setContent($some_text)
  ->setAuthor($some_user) // AppBundle\Entity\User
  ->addFile($file1)
  ->addFile($file2);

$em->getRepository('AppBundle:Post')->insert($post);

// Getting company and department
$company    = $em->getRepository('AppBundle:Company')->findOneByCode($some_company_code);
$department = $em->getRepository('AppBundle:Department')->findOneByCode($some_dept_code);

$company->addFile($file1)->addFile($file2);
$department->addFile($file1)->addFile($file2);

$em->getRepository('AppBundle:Company')->update($company);
$em->getRepository('AppBundle:Department')->update($department);

// Notifications
$notif = new Notification(); // AppBundle\Entity\Notification
$notif->setText("Text")
  ->setPost($post)
  ->addAddressee($some_dept_member)
  ->addAddressee($other_dept_member);

$notif = $em->getRepository('AppBundle:Notification')->insert($notif);

1 个答案:

答案 0 :(得分:0)

在存储库中,您应该仅使用DQL获取实体或执行查询以检索某些数据。

每次需要在数据库中创建新行时,都必须通知实体管理器您要保留实体,并调用$em->persist($myNewEntity)。这告知实体管理器该实体应该保持为dB。

创建(并保留)所有实体和/或修改获取的实体后,您只需调用$em->persist()一次:实体管理器将在单个事务中执行所有必需的插入/更新/删除操作到你的dB。

如果您还需要在同一事务中检索/获取数据,您应该考虑将所有代码包含在回调函数中并将其传递给实体管理器,如下所示

$myCallback=function($em) {
    //Do all here: access repositories, create new entities, edit entities
    //...
    //no need to call $em->flush(), it will be called by Doctrine after the execution of the callback
};
$em->transactional($myCallback) ;