2013-03-01 99 views
1

我想向我的教义模型添加安全层。为了能够在SQL级别的教义过滤器中添加权限检查,我必须维护一些数据库表,其中包含为每个实体计算的访问控制令牌的高速缓存。onFlush事件处理程序中的繁重更新和删除

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

它记录了如何坚持新实体以及如何改变已存在实体的关联和原始属性。这是通过调用工作单元的computeChangeSet()或者重新计算SingleEntityChangeSet()来完成的,并且通过将每个实体传递给这些方法之一来完成。整个系统在这些更新期间必须锁定,虽然它们很少,但应尽快完成。此外,我不知道如何删除实体,甚至无需先读出所有实体即可截断整个表。

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

回答

4

首先,onFlush是非常强大的,所以你在这里可能是过度思考。

要在onFlush删除实体,只是安排他们在你的听众去除:

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

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

    $uow->computeChangeSet(); 
} 

要处理海量的更新,你可以:

  • 使用DQL查询来更新实体您想要处理
  • 使用来自data-fixtures库的ORMPurger来处理诸如截断表的操作(重现其逻辑或使用具有子集的第二个实体管理器可用的元数据和相同的连接)
  • 正如你所说的,在连接上直接工作:你是在一个事务中,所以它是绝对安全的

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

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

+0

谢谢。很高兴知道remove()在onFlush()和DQL以及锁定方法(可能)中也可以工作。 – stofl 2013-03-01 16:45:49

相关问题