2013-03-01 98 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

相關問題