2017-08-09 41 views
0

在某个控制器中,我需要在数据库中执行多次插入/更新。我为此使用了4个实体库,但我需要在一个工作单元中完成这个工作。Symfony。使用与2+储存库的交易

我知道我可以在控制器上直接做这些插入/更新和使用$em->getConnection()->beginTransaction()$em->getConnection()->rollBack()$em->getConnection()->commit(),以确保所有或没有完成。但是这不符合symfony的最佳实践,所以我想使用存储库。

对于Doctrine 1我见过this tutorial,但它似乎是一个非常复杂的解决方案,应该是比较简单的。

有什么想法?

预先感谢您。

编辑,我正在使用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); 
+0

首先,你”我问了一个非常广泛的问题。没有任何代码很难提供帮助。接下来的事情是,存储库不应该修改数据,而只是为了获取它,所以存储库不是这种工作的地方。 –

+0

当'flush()'被调用时,不会自动将单个事务中的所有调度操作包装在一起吗?可能这可以帮助:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/transactions-and-concurrency.html – Joe

+0

@Jakub,我没有写任何代码,因为我认为任何使用过symfony的人都可以知道我在问什么。另外,我想这是大多数人都面临的问题,所以对于我来说,在这里我没有找到任何答案,这有点令人惊讶。文档中提到了有关存储库的信息“Doctrine提供了特殊的存储库类,允许您将所有查询逻辑保存在一个中心位置”。这就是为什么我想这样做。 Joe,我知道如何使用事务,但文档没有解释我在问什么(或者我没有找到) – DandyCC

回答

0

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

每次您需要在您的数据库中创建一个新行时,您必须通知实体经理您要坚持该实体,请拨打$em->persist($myNewEntity)。这通知实体经理该实体应该被保持为dB。一旦创建(并持久保存)了所有实体和/或修改了您提取的实体,您只需拨打$em->persist()一次即可:实体管理器将在单个事务中完成所有需要的插入/更新/删除操作。

中,你应该考虑在回调函数所有的代码,并把它传递到实体管理器相同的交易如果您还需要检索/读取数据,这样

$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) ;