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

标签 php mysql doctrine-orm

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

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

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

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

最佳答案

首先,onFlush的功能很强大,估计是你想多了。

要在 onFlush 中删除实体,只需安排它们在您的监听器中删除:

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

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

    $uow->computeChangeSet();
}

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

  • 使用 DQL 查询更新您要处理的实体
  • 使用ORMPurger从数据夹具库处理截断表等操作(复制其逻辑或使用具有可用元数据子集和相同连接的第二个实体管理器)
  • 如您所说,直接在连接上工作:您正在进行交易,因此非常安全

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

有一整章关于 transactions, concurrency and locking in the ORM 的文档.据我所知,所有这些操作在 onFlush 期间也是有效的。

关于php - onFlush 事件处理程序中的大量更新和删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15158617/

相关文章:

php - 回显列表中的元素并对齐它们

php - 尝试使用 PHP 和 XPath 删除目录中的 ID 匹配文件

php - 数据库 四表数据完整性

php - 使用 php 用 css 设计一个词

javascript - 我怎样才能从php中获取数据到js

c# - ExecuteNonQuery 返回 1,即使更新语句没有影响任何行

mysql - 选择 friend 的 friend mysql

php - Mysql 中的数组 WHERE LIKE?

php - 在 Symfony 1.4 和 Doctrine 中使用一个查询插入多行

php - 如何访问 symfony 存储库中的创建查询方法