在 Symfony 2.6 上使用 Doctrine 是否有办法“检测”已持久化的实体上的事务回滚?
我原来的问题:我创建了代表文件系统上文件的新实体。在 $em->persist()
上,这些实体通过 Doctrine 的 PrePersist 事件将文件从 /temp
目录移动到最终目的地。如果我正在处理的事务稍后在代码中回滚,则不会在数据库中创建任何行,但文件仍然存在,我必须在 $em->rollback()
之后手动删除它们> 有了额外的代码,每次我这样做。所以我认为可能有一个事件我可以用来检测实体已从更改列表中“删除”或“回滚”,因此我可以删除该实体的相关文件。
还有:PostPersist 或 PostFlush 事件似乎可以解决我的问题,但如果我有多个 $em->flush()
指令和代码下方的指令抛出一个异常,我在整个事务上执行了 $em->rollback()
,我仍然得到了延迟文件
最佳答案
Doctrine 默认没有回滚事件。但是您可以做的是扩展 Connection 类并引发您自己的事件:
<?php
namespace Acme\MyBundle\Doctrine\DBAL;
use Doctrine\DBAL\Connection;
use Ozean12\ApiSDKBundle\Doctrine\Event\PostCommitEventArgs;
use Ozean12\ApiSDKBundle\Doctrine\Event\PostRollbackEventArgs;
/**
* Class ConnectionWrapper
*/
class ConnectionWrapper extends Connection
{
/**
* {@inheritdoc}
*/
public function commit()
{
parent::commit();
if (!$this->isTransactionActive()) { // to be sure that we are committing a top-level transaction
$this->getEventManager()->dispatchEvent(PostCommitEventArgs::NAME, new PostCommitEventArgs());
}
}
/**
* {@inheritdoc}
*/
public function rollBack()
{
parent::rollBack();
if (!$this->isTransactionActive()) { // to be sure that we are rolling-back a top-level transaction
$this->getEventManager()->dispatchEvent(PostRollbackEventArgs::NAME, new PostRollbackEventArgs());
}
}
}
然后将此类声明为连接包装器:
doctrine:
dbal:
wrapper_class: Acme\MyBundle\Doctrine\DBAL\ConnectionWrapper
并创建您的事件类和订阅者。您可以通过监听 onFlush 事件来跟踪同一订阅者类中的持久化实体,以便在发生提交或回滚时对它们执行操作。
关于php - 有学说回滚事件吗?即对有回滚的更改列表中的实体执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31306147/