有教义回滚事件吗?即对有回滚的变更列表上的实体进行处理

jua*_*uan 5 php symfony doctrine-orm

在Symfony 2.6上与Doctrine合作是否有办法“检测”已持久存在的实体的事务回滚?

我最初的问题:我创建了代表文件系统上文件的新实体。在$em->persist()这些实体上,/temp通过Doctrine的PrePersist事件将文件从目录移动到最终目标。如果稍后要在代码中回滚我正在处理的事务,则不会在数据库上创建任何行,但是$em->rollback()每次执行此操作时,文件都会流连忘返,我必须在使用额外的代码后手动删除它们。因此,我认为可能会有一个事件可以用来检测某个实体已从变更列表或“回滚”中“删除”,因此我可以删除该实体的相关文件。

:PostPersist或PostFlush事件似乎可以解决我的问题,但是如果我有多$em->flush()条指令,并且代码中下面的一条引发异常,而我$em->rollback()在整个事务中都这样做,则仍然会得到文件

小智 6

默认情况下,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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将此类声明为连接包装器:

doctrine:
  dbal:
    wrapper_class:  Acme\MyBundle\Doctrine\DBAL\ConnectionWrapper
Run Code Online (Sandbox Code Playgroud)

并创建您的事件类和订阅者。您可以通过监听onFlush事件来跟踪同一订户类中的持久化实体,以便在发生提交或回滚时可以对它们执行操作。