はじめに
こんにちは。にんじんです。
少し前に上げたこちらの記事。最後のトランザクションについては詳細を割愛していたのですが、
ああ、これはエントリを執筆しなければ!!!と熱意の湧く事態が発生したので、
今回はトランザクションについて絞って、コーディングのポイントを書いていきたいと思います。
基礎の基礎編
ご存知の方も多いかもしれませんが、念のため、改めてSpring Bootでのトランザクションの実装方法を記載します。
基本形
@Service public class SampleService { @Transactional public void save() { (なんらかしらの保存処理) } }
こちらが基本形です。
何かしらのメソッドに@Transactional
というアノテーションを付けることで、このメソッドが1トランザクションになります。
ロールバック対象を増やす
@Service public class SampleService { @Transactional(rollbackFor=Exception.class) public void save() { (なんらかしらの保存処理) } }
このように、rollbackFor=xxxException.class
を設定すると、
デフォルトではロールバックされないException
が発生された場合にもトランザクションがロールバックされるようになります。
デフォルトは、非検査例外(RuntimeException
を継承したException
クラス)なので、検査例外ではロールバックされません。
プロジェクトのお作法によって、必要に応じて付与することになります。
よくある間違い編
さて問題です
@Service public class SampleService { public void mainTask() { save(); } @Transactional private void save() { (なんらかしらの保存処理) } }
上のトランザクションの実装で誤っている点を2つ答えてください。
・・・・
・・・・
・・・・
考えていただけたでしょうか。
それでは、回答です。
回答その1
@Transactionalのアノテーションはpublicメソッドにつけるべし!!
@Service public class SampleService { @Transactional public void save() { (なんらかしらの保存処理) } }
最初に上げた基本形と同じように、public
のメソッドにアノテーションを付与した場合のみ、ロールバックが有効になります。
private
はもちろん、パッケージプライベートもprotected
もだめです。
回答その2
@Transactionalのアノテーションをつけたメソッドは、別のクラスから呼び出すべし!!
@Controller public class SampleController { @Autowired private SampleService service; @RequestMapping public void mainTask() { service.save(); } }
@Service public class SampleService { @Transactional public void save() { (なんらかしらの保存処理) } }
同じクラスからの呼び出しでは、いくらpublic
のメソッドでもロールバックされません。
あと、Spring
の機能を使ったロールバックを行うので、当然のように単なるドメインクラスからの呼び出しもNGです。1)そんなことをする人はいないと思いますが
上の例のようにControllerからServiceを呼び出すや、ServiceからComponentを呼び出す、というように使いましょう。
おわりに
今回はトランザクションの実装方法についてまとめてみました。
何が難しいって、正常に挙動していれば、ロールバックは発動しないことですよね。
とはいえ「予期せぬ不具合が100%発生しない」なんてことはあり得ないのが現実世界。
もしものときにトランザクションが正しく動かず、一部のデータだけコミットされてしまったら、、、
システムが取り扱っている内容にもよりますが、少なくとも面倒くさい事態になることは請け合いです。
私もこの記事を書いて、改めてトランザクションの重要性を心に刻みました。
本記事を執筆するにあたって、こちらの公式リファレンスを参照しました。
慣れてくるとおざなりにしてしまいがちですが、
ライブラリやフレームワークを使う際は、きちんと公式リファレンスを参照するようにしないとですね。
それでは、みなさまも快適なコーディングライフを!
注訳はこちら
↑1 | そんなことをする人はいないと思いますが |
---|