自主的20%るぅる

各々が自主的に好き勝手書くゆるふわ会社ブログ

Spring Bootで実装するときに気をつけて欲しいポイント~トランザクション編~

はじめに

こんにちは。にんじんです。

Spring Bootで実装するときに気をつけて欲しいポイントベスト3~構成編~

少し前に上げたこちらの記事。最後のトランザクションについては詳細を割愛していたのですが、
ああ、これはエントリを執筆しなければ!!!と熱意の湧く事態が発生したので、
今回はトランザクションについて絞って、コーディングのポイントを書いていきたいと思います。

基礎の基礎編

ご存知の方も多いかもしれませんが、念のため、改めて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%発生しない」なんてことはあり得ないのが現実世界。
もしものときにトランザクションが正しく動かず、一部のデータだけコミットされてしまったら、、、
システムが取り扱っている内容にもよりますが、少なくとも面倒くさい事態になることは請け合いです。
私もこの記事を書いて、改めてトランザクションの重要性を心に刻みました。

https://spring.pleiades.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative-annotations

本記事を執筆するにあたって、こちらの公式リファレンスを参照しました。
慣れてくるとおざなりにしてしまいがちですが、
ライブラリやフレームワークを使う際は、きちんと公式リファレンスを参照するようにしないとですね。

それでは、みなさまも快適なコーディングライフを!

注訳はこちら   [ + ]

1. そんなことをする人はいないと思いますが
Let’s share this article!

{ 関連記事 }

{ この記事を書いた人 }

にんじん
にんじん

大阪でJava・C#の開発やってます。現場では生き字引になりがち。
ブログのアイキャッチに自分で撮った写真を使うのがマイブーム。

記事一覧