原则:循环中的原子更新和异常

问题描述

我们正在将项目从更基本的ORM迁移到使用Symfony + Doctrine。在项目中,我们有很多cron作业,如下所示:

myList

当我们这样做时,try catch中的所有更改都是原子性的,而同时又有可能从错误中恢复并继续下一个$ row。

在Symfony + Doctrine中,我根本无法弄清楚如何模仿这种行为。 Doctrine建议处理异常的方法关闭EntityManager,但如何恢复?

解决方法

ORM在flush上隐式地执行此操作,因此大多数时候您可以避免自己进行操作的麻烦。

但是,如果您想进行清晰的分界,您仍然可以采用与到目前为止相同的方式明确地进行分界。

此处有更多阅读内容和示例:https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/transactions-and-concurrency.html

与以下评论相关的编辑:

您应该注入注册表,而不是注入管理器。 赶上之后,您可以检查是否$em->isOpen(),如果不是请致电$registry->resetManager()

我怀疑这也会重置工作单元,因此您可能会遇到分离的实体。在这种情况下,您应该进行$em->merge();

这里要注意的一件事是,期望在理论上不被认为是正常的,因此他们正在关闭经理。您可能会认为这是过分夸张的-是的,因为您正在违背这里的哲学。如果可以,请验证您的数据。阅读本节:https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/transactions-and-concurrency.html#exception-handling

原因:(根据我的知识,这不是官方的)经理内部工作单元是有状态的对象。在事务期间发生异常时,该状态将保持不变,但不会持久化到数据库中。如果他们放手,这将意味着EM将尝试再次应用所有状态更改,并再次遇到相同的异常。因此,在相同状态下保持打开状态毫无意义,需要进行重置。