Labyrinth of Wisdom

-This is My Archive-


【Apex】DB操作を取り消す方法(ロールバック)

データベースへの更新を取り消すロールバックをApexで実装したかったので、調べた結果をまとめたいと思います。

ついでにその際に起こった欠番現象にも少し触れています。

サンプルコード

複数のオブジェクトを更新するサンプルコード。

try文で一つでもDmlExceptionのエラーがあると、catch文に移動してロールバックポイントまで戻ります。

今回のサンプルではaccountもしくはcampaigninsertがどちらか一方でもDmlExceptionを引き起こした場合、両方のインサートが取り消されます。

Account account = new Account(Name = 'aaa');
Campaign campaign = new campaign(Name = 'bbb');

// ロールバックした際に戻るポイント
Savepoint sp = Database.setSavepoint();

try{
    insert account;
    insert campaign;
}catch(DmlException e){
    // 引数に戻るポイントを指定
    Database.rollback(sp);
}

欠番の可能性

オブジェクトのカラムに自動連番がある、かつロールバックが何回か発生した後でinsertに成功した場合には番号に抜け(欠番)が生じる可能性があります。

例:

  • 1回目

    insert account => 成功 , insert campaign => 失敗

    ロールバック実行 => レコード登録取り消し

  • 2回目

    insert account => 成功 , insert campaign => 成功

    レコード登録成功

  • 結果

Accountオブジェクト

No. Name
2 aaa

Campaignオブジェクト

No. Name
1 bbb

このようにロールバックをしていても、Accountオブジェクトレコードの番号は2で採番されてしまいます。 なんか気持ち悪い・・・。(レコードはちゃんと一個しかないんですが)

ただ、それらは気にするものでもないという意見がこちらに書かれているので、僕はそれを見習おうかと思います。 気になる方は一度見てみてください。

その他ロールバックの詳しいことは下記の参考サイトが詳しいです。

参考

[salesforce]APEXコードにおけるトランザクションとロールバック – deferloader