Salesforce技術ブログ(MIXED_DML_OPERATIONエラーの回避について)

Salesforce技術ブログ(MIXED_DML_OPERATIONエラーの回避について)

Salesforce技術ブログ(MIXED_DML_OPERATIONエラーの回避について)

こんにちは!"なかばゆう"こと中林です!


Salesforceでは、1トランザクション内で設定オブジェクトと非設定オブジェクトに対して、DML処理を行おうと

した場合、以下のエラーが発生してしまいます。

 

「MIXED_DML_OPERATION, 非設定オブジェクトを更新した後の設定オブジェクト上のDML操作

(またはその逆)は、許可されていません」

 

今回は、少し力技ではありますが、このエラーの回避方法についてです。

 

 

★MIXED_DML_OPERATIONエラーの回避について

 

設定オブジェクトとは、ユーザオブジェクトや、ロールオブジェクトなどが該当します。

非設定オブジェクトとは、取引先、取引先責任者、カスタムオブジェクトなどです。

 

上記エラーは、設定または非設定オブジェクトに対するDML処理のどちらかを、

futureアノテーションのついた非同期メソッドで実行することで、回避可能です。

 

 @future

 private static void insertAcounnt(){

     Account acc = new Account ();

     acc.Name = ''TEST取引先;

     insert acc;

}

 

しかし、非同期メソッドはプリミティブデータ型、プリミティブデータ型の配列、プリミティブデータ型の

コレクション(List,Mpa)のみを引数に設定可能となっており、sObjectは引数に設定することができない

ため、List<Account>などあらかじめ用意したsObject型のリストを非同期メソッドに渡してDML処理を

実行・・・・といったことはできません。

 

そこで、強引ではありますが、以下のように一度レコードの値をカンマ区切りで1つの文字列にして引数に

渡し、非同期メソッド内でカンマで文字列に分割し、各項目の値として設定することで、対処することが

できます。

 

public void save(){

   // 設定オブジェクトレコード更新

   update user;

   // 取引先更新処理

   List<String> accList = new List<String>();

   String acc1 = 'テスト取引先,000-0000-0000,300';// 取引先名、電話、従業員数の順番

   String acc2 = 'サンプル会社,111-111-111,200';

   accList.add(acc1);

   accList.add(acc2);

   // 非同期メソッド呼び出し

   insertAcounnt(accList);

}

@future

private static void insertAcounnt(List<String> accList){

   List<Account> accList = new List<Account>();

   for(String str : accList){

       Account acc = new Account ();

       // カンマで分割してリストに格納

         List<String> strList = str.split(',', -1);

 

      acc.Name = strList[0];//取引先名

      acc.Phone = strList[1];//電話

      acc.NumberOfEmployees = Integer.valueof(strList[2]);//従業員数

      accList.add(acc);

     }

    insert accList;

 }

 

引数を文字列のリストにすることで、複数件のレコードを処理することも可能です。

ただし、引数項目が増えると、何番目にどの項目が入っているのか・・・・分かりにく

いという問題はありますが、どうしても設定オブジェクト、非設定オブジェクトを同時に

更新する必要がある場合は、検討の1つとしても良いと思います。