2012-06-29 30 views
3

我在刪除觸發器之前運行Apex作業,並注意到通過Salesforce界面刪除單個Campaign需要大約34秒,並且刪除了Campaign時Apex作業已完成運行。當我使用VisualForce頁面在相同數量的記錄(15,000)上運行相同的Apex作業時,Apex作業排隊並在VisualForce頁面完成後運行。頂點作業未在觸發器中異步運行

在這個屏幕截圖中,第一份工作是使用VisualForce第二和第三排隊使用觸發器排隊:

Apex Jobs

正如你可以看到雖然相同數量的記錄(15,000)被處理在使用觸發器批次排隊時創建相同的Apex作業且提交和完成日期完全不同。

的Apex作業在排隊觸發:

trigger DeleteChilds on Campaign (before delete) { 
public static final Integer MAX_DELETED = 500; 
Set<ID> ids = new Set<Id>(); 
List<Parent__c> objs = new List<Parent__c>(); 

for(Campaign c : Trigger.old) 
    ids.add(c.Id); 

objs = [SELECT Id FROM Parent__c WHERE Campaign__c IN :ids]; 

ids = new Set<Id>(); 

for(Parent__c s : objs) 
    ids.add(s.Id); 

Integer childCount = [SELECT count() FROM Childs__c WHERE Parent__c IN :ids]; 

if(childCount < MAX_DELETED){ 
    List<Childs__c> childs = [SELECT Id FROM Childs__c WHERE Parent__c IN :ids]; 

    delete childs; 
} else {     
    String deleteQuery = 'SELECT Id FROM Childs__c WHERE '; 

    for(ID id : ids){ 
     deleteQuery += String.format(' Parent__c = \'\'{0}\'\' OR', new String[] {id}); 
    } 

    if(deleteQuery.endsWith('OR')){ 
     deleteQuery = deleteQuery.substring(0, deleteQuery.length() - 2); 
    }    

    BatchDeleteChilds batch = new BatchDeleteChilds(); 
    batch.deleteQuery = deleteQuery; 

    ID batchId = Database.executeBatch(batch);  
} 

delete objs; 
} 

這是頂點工作:

global class BatchDeleteChilds implements Database.Batchable<sObject> { 
public String deleteQuery; 

global Database.QueryLocator start(Database.BatchableContext context){ 
    return Database.getQueryLocator(deleteQuery); 
} 

global void execute(Database.BatchableContext context, List<sObject> records){ 
    delete records; 
    DataBase.emptyRecycleBin(records); 
} 

global void finish(Database.BatchableContext context){ 

} 
} 

有其他人遇到這樣的事情?

謝謝,

+0

有趣的問題。你可以運行調試登錄並共享結果嗎?可以幫助確定可能沒有報告爲批處理上下文錯誤的問題。另外,最好在刪除後的上下文中運行它嗎?以防萬一該活動無法刪除。那麼你不會失去孩子的記錄。 –

+0

將觸發器更改爲在父對象的Campaign__c字段中的刪除結果爲空之後運行,因爲Campaign已被刪除。這會導致沒有刪除,因爲[SELECT Id FROM Parent__c WHERE Campaign__c IN:ids]不會返回任何結果。 – mob1lejunkie

回答

2

你正在尋找一種競爭條件,你可能永遠都不會贏。在您的批處理作業執行時,已經被刪除的父對象將被提交,這會將數據庫中從子項到父項的查找置零。因此,您傳入批次的查詢將有零個記錄。

  • 預刪除子:(名稱= '示例',parent__c = '123')
  • 後刪除(預批處理)兒童:(名稱= '示例',parent__c = NULL)

我不知道推動這種方法的設計決策,但還有其他選項可用於批量刪除子記錄。最簡單的方法是將孩子與父母的關係作爲主要細節。使用這種類型的關係會自動刪除子記錄。

其次,您可以使用visualforce頁面覆蓋父對象的刪除按鈕。然後控制器會計數這些孩子,並決定是否啓動批處理來刪除它們。然後讓批處理進程等待刪除父對象,直到完成方法。

+0

我在Apex Job上決定的原因是響應式界面。儘管從接口刪除父對象將導致刪除所有子對象,但頁面加載需要35秒才能完成10,000個子對象。 – mob1lejunkie

+0

我看到,覆蓋刪除按鈕聽起來像是一個很好的選擇。讓我知道這是否適合你。 –