onFlush事件处理程序中的大量更新和删除

sto*_*ofl 1 php mysql doctrine-orm

我想在我的学说模型中添加一个安全层。为了能够在SQL级别的原则过滤器中添加权限检查,我必须维护一些数据库表,其中包含为每个实体计算的访问控制令牌的缓存。

现在,我必须更新这些表,并且在某些情况下,我必须完全重建这些缓存表之一。这必须在侦听onFlush事件的事件侦听器中完成。存档(最好的性能和最可靠的)方式是什么?

该文档记录了如何持久存储新实体,以及如何更改已持久存储的实体的关联和原始属性。这是通过调用工作单元对象的computeChangeSet()或recomputeSingleEntityChangeSet()并将每个单个实体传递给这些方法之一来完成的。在这些更新过程中,必须锁定整个系统,尽管这种情况很少见,但应尽快完成。另外,我不知道如何删除实体甚至截断整个表,而不必先读出所有实体。

  • 如何在onFlush事件中删除实体?
  • 如何在onFlush事件中进行批量更新(表截断和数十万条记录的插入)?我想在这种情况下可以使用$ EntityManager-> getConnection()-> executeUpdate(),对吗?
  • 如何在onFlush事件中锁定表(读取)?

Ocr*_*ius 5

首先,onFlush它非常强大,因此您可能想得太过分了。

要删除中的实体onFlush,只需安排在侦听器中将其删除:

public function onFlush(OnFlushEventArgs $eventArgs) {
    $em  = $eventArgs->getEntityManager();
    $uow = $em->getUnitOfWork();

    foreach ($uow->getScheduledEntityUpdates() as $updated) {
        $em->remove($updated);
    }

    $uow->computeChangeSet();
}
Run Code Online (Sandbox Code Playgroud)

要处理大量更新,您可以:

  • 使用DQL查询来更新您要处理的实体
  • 使用数据夹具库中的ORMPurger处理诸如截断表之类的操作(重现其逻辑或将第二个实体管理器与可用元数据的子集和相同连接一起使用)
  • 如您所说,直接进行连接:您正在事务中,因此非常安全

请记住,在不更新应用程序级对象的情况下更改数据库状态(大量更新/删除)是有风险的,因此请考虑在执行此操作后清除实体管理器。

整个文档章节都涉及ORM中的事务,并发和锁定。据我所知,所有这些操作在期间都有效onFlush