更新用户对象时 Salesforce Apex 触发器中的 MIXED_DML_OPERATION 错误

Posted

技术标签:

【中文标题】更新用户对象时 Salesforce Apex 触发器中的 MIXED_DML_OPERATION 错误【英文标题】:MIXED_DML_OPERATION error in Salesforce Apex Trigger when updating User objects 【发布时间】:2012-04-25 13:06:57 【问题描述】:

我在联系人对象上有一个触发器,当我尝试更新此触发器中的用户记录时,我收到以下异常:

“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;


从联系人触发器更新用户记录字段时如何避免此错误?

【问题讨论】:

【参考方案1】:

Salesforce 将对象分类为所谓的设置对象和非设置对象。 User 是一个设置对象,而 Contact 是一个非设置对象。 Salesforce 限制 DML 操作,因此不能在同一上下文中操作这两种对象。

有解决此问题的解决方法,将冲突对象的 DML 代码放置到 @future 方法中,如本 document 末尾和上一个答案中所述。

在我的情况下,使用 @future 方法不起作用,因为 User 上有一个更新触发器调用了另一个 @future 方法,而 Salesforce 不允许从另一个 @future 方法调用 @future 方法。

所以我想出了另一种解决方法,适用于用户对象的某些情况。

从 API 版本 15.0 开始,Salesforce 实际上允许在与非设置对象更新相同的上下文中更新用户对象的自定义字段。因此,如果您需要更新用户的标准字段,您可以在用户对象上使用带有“更新前”触发器的自定义代理字段。

如果您需要更改用户的 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();
    

【讨论】:

是的,我已经尝试过这种方法,但它对我不起作用,因为用户上有一个触发器,它调用“@future”方法并从另一个“@future”调用“@future”方法Salesforce 中不允许使用方法。我找到了解决问题的替代解决方法,稍后我将其作为答案发布。谢谢回复!

以上是关于更新用户对象时 Salesforce Apex 触发器中的 MIXED_DML_OPERATION 错误的主要内容,如果未能解决你的问题,请参考以下文章

Apex 中操作用户和组

APEX 中的 Salesforce UserInfo 会话类型

Salesforce自主学习

Salesforce Apex学习 : 利用Schema命名空间中的DescribeSObjectResult类型来获取sObject对象的基本信息

Apex 中的参考父对象

Apex Scheduler Salesforce,执行错误