【问题标题】:Prevent Doctrine EntityListener postRemove being wrapped in transaction防止 Doctrine EntityListener postRemove 被包裹在事务中
【发布时间】:2016-03-28 21:21:08
【问题描述】:

我已经设置了一个学说 EntityListener。我需要在postRemove 事件中执行一些代码,这些代码必须在任何原则事务之外。然而:

public function postRemove(Image $image, LifecycleEventArgs $event)
{
    $isActive = $event->getEntityManager()->getConnection()->isTransactionActive();
    dump($isActive);
}

总是转储 true

无论我是在 postRemove() 方法中提交还是刷新;我尝试在 preRemove() 中启动事务并在 postRemove() 中提交它,但这没有帮助。

问题:有没有办法阻止 Doctrine 将 postRemove() 包装到事务中?如果不是,对我来说执行超出事务的代码的最佳方式是什么?我不在乎它是立即发生还是在内核终止时发生,只要它最终发生。

我有个想法,在 EntityListener 中创建一个析构方法,并在 Listener 析构时运行代码,但我不知道这有多可靠。也许还有其他(更好的)选择?

谢谢!

【问题讨论】:

    标签: transactions doctrine symfony


    【解决方案1】:

    听起来你想刷新或持久化,这不是你想在 postRemove 事件中做的事情。

    来自文档:

    这里的更改与数据库中的持久性无关, 但是您可以使用这些事件来更改不可持久化的项目,例如 非映射字段、日志记录甚至关联的类 由 Doctrine 直接映射。

    因此,此事件不适用于使用实体管理器执行操作。

    请改用onFlush listener。您可以捕获已删除实体的实例并执行适当的操作。仔细阅读文档,尤其是以下限制适用于 onFlush 事件部分

    http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/events.html#onflush

    【讨论】:

    • 文档说在 onFlush 事件中调用 EntityManager::flush() 也是一个坏主意。我的问题是:在持久化新图像时,我想创建该图像的几种格式,将这些格式保存到文件系统,并在另一个表中引用(行)这些文件。为了不在文件系统和数据库之间出现不一致,我需要在每次 fs 写入操作后刷新。但事实证明,我既不能在 pre/postPersist 中也不能在 onFlush 中刷新?
    • 也许在 EntityListener 中完成所有这些工作毕竟是个坏主意?
    • 您不需要调用flush,您使用unitofwork进行更改并持久化,然后重新计算更改集,完成。这是我回答的另一个问题的示例:stackoverflow.com/questions/30734814/… - 这很有效,我在现场生产系统中使用它。
    猜你喜欢
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    • 2013-09-22
    相关资源
    最近更新 更多