[SFDC]MIXED_DML_OPERATION例外が発生して辛いです…

Force.comで「グループ情報」というカスタムオブジェクトを作った。
グループの登録と同時に自動でグループ用のロールを作成する動きを実現したかったのだが苦戦した。

最初に試したのはオブジェクトにトリガーを仕掛ける作戦。
グループのAfter Insertのタイミングでトリガーを起動してロールを作成するというもの。

普通にこれでいけそうじゃん、と思ってトリガ作って仕掛けるもロールが登録されない。
ログを見たらトリガ実行時に「MIXED_DML_OPERATION」とかいう例外が発生しとる。

調べると、これはApexの仕様で、
「1トランザクション内で設定オブジェクトと非設定オブジェクトを同時にDML操作できない」
という制約があるそうな。
今回の場合だとロールは設定オブジェクト、カスタムオブジェクトは非設定オブジェクトにあたる。

…仕様であれば仕方がない。

じゃあどうするかって考えて、紆余曲折を経て拡張コントローラクラスにメソッドを用意して、
その中で標準コントローラのsave()とロール登録用の@futureなメソッドを実行することにした。

Apexページに「保存」ボタンみたいなのを用意してcreateGroupAndRoleを呼ぶ。
とりあえずこれで期待通りに動くことは動く。
拡張コントローラに標準コントローラを持っておくのが良いのかどうか知らんけど。
ロール登録用メソッドasyncCreateRoleForGroupは’@future’アノテーションをつけて非同期に実行されるようにする。
@futureアノテーションについて
これでグループ登録とロール登録のトランザクションが分離され、MIXED_DML_OPERATION例外は発生しなくなる。

最初は@remoteActionなメソッドを2つ(グループ登録用とロール登録用)準備しておいてAjaxで処理しようかなと考えたのだけど、
グループ登録時の入力チェックやエラーメッセージ表示がだいぶ面倒だったので標準のsave()を利用することに落ち着いたのだ。

「MIXED_DML_OPERATION例外の対策はトランザクションを別にすることだ(キリッ」ってほとんどギャグだけど他にやりようも無さそうなのでしゃーない。
ロール登録時に処理がこけたらどうすんすかぁー、てのは対策をおいおい考えよう……
日時バッチみたいなのでグループを舐めて対応するロールがなければ補ってあげるみたいな感じにしようそうしよう。


コメントを残す