2012-04-13 53 views
3

我有一個聯繫對象的觸發,當我嘗試更新這觸發我得到以下異常的用戶記錄:在設置MIXED_DML_OPERATION錯誤在Salesforce的Apex觸發時更新用戶對象

「MIXED_DML_OPERATION,DML操作用戶,原來的對象:你已經更新完畢後未設置對象(反之亦然),對象是不允許的聯繫」

觸發代碼:

trigger UpdateContactTrigger on Contact (after update) { 

    User u = [SELECT Id, IsActive FROM User WHERE IsActive = true]; 

    u.IsActive = false; 
    update u; 

} 

我怎樣才能避免這種錯誤,同時更新用戶記錄的來自Contact觸發器的字段蒙古包?

回答

9

Salesforce的對象分類成所謂的設置和非設置對象。用戶是設置對象,而聯繫人是非設置對象。 Salesforce限制DML操作,因此這兩種對象不能在同一個上下文中操作。

這個問題的解決方法是將衝突對象的DML代碼放置到這個document末尾描述的@future方法和上一個答案中。

在我的情況下,使用@future方法不起作用,因爲User上有一個更新觸發器,它調用另一個@future方法,並且Salesforce不允許從另一個@future方法調用@future方法。

因此,我想出了另一種解決方法,適用於某些User對象的情況。

從API版本15.0開始,Salesforce實際上允許在與非設置對象更新相同的上下文中更新User對象的自定義字段。因此,如果您需要更新用戶標準字段,則可以在用戶對象上使用帶有「更新前」觸發器的自定義代理字段。

如果需要更改用戶的isActive域,自定義IsActiveProxy字段添加到用戶和它在觸發執行您的更新:

trigger UpdateContactTrigger on Contact (after update) { 

    User u = [SELECT Id, IsActive FROM User WHERE IsActive = true]; 

    u.IsActiveProxy__c = false; 
    update u; 

} 

然後創建一個用戶一個「更新前」觸發器將代理字段值複製到標準字段:

trigger BeforeUpdateUserTrigger on User (before update) { 

    for(User user : trigger.new) { 

     if(user.IsActive != user.IsActiveProxy__c) { 
      user.IsActive = user.IsActiveProxy__c; 
     } 

    } 

} 

就是這樣!它爲我工作。

2

您應該定義@future方法,它將執行更新並從觸發器調用此方法。

@future 
updateUser(){ 
    User u = [SELECT Id, IsActive FROM User WHERE IsActive = true]; 

    u.IsActive = false; 
    update u; 
} 

,並調用它在觸發:

trigger UpdateContactTrigger on Contact (after update) { 
    updateUser(); 
}  
+0

是的我已經嘗試過這種方法,但它不適用於我,因爲用戶觸發了一個觸發'@future'的方法,並且不允許在另一個'@future'方法中調用'@future'方法銷售隊伍。我找到了解決問題的替代解決方法,稍後我會將其作爲答案發布。感謝您的回覆! – 2012-04-13 08:00:13