SpringBootでtry/catchを使用して例外をキャッチし、トランザクションをロールバックする方法(自動ロールバック/手動ロールバック/一部のロールバック)

SpringBoot

SpringBoot 

概念

Springの公式ドキュメントによると、Transaction内でunchecked exceptionが発生する場合、自動的にrollbackされますが、checked exceptionが発生する場合は自動的にrollbackされません。

ここで、checked exceptionとunchecked exceptionの概念を明確にする必要があるのは、次の理由からです。

Springは宣言的トランザクション処理を使用しており、アノテーションが付けられたデータベース操作メソッドでunchecked exceptionが発生した場合、すべてのデータベース操作がrollbackされます。 例外がchecked例外である場合、デフォルトではデータベース操作がコミットされます。

checked例外

無効で、プログラムで予測できないことを示します。

無効なユーザー入力、ファイルが存在しない、ネットワークまたはデータベース接続エラーなどがあります。これらはすべて外部の原因であり、プログラム内で制御できません。 明示的にコードで処理する必要があります。

たとえば、try-catchブロックで処理するか、所属するメソッドにthrows宣言を追加して、例外を呼び出し元に投げる必要があります。 java.lang.Exception(java.lang.RuntimeExceptionを除く)から継承されます。

unchecked例外

エラー、プログラムの論理エラーを示します。

IllegalArgumentException、NullPointerException、IllegalStateExceptionなど、RuntimeExceptionのサブクラスです。

コードで明示的にunchecked例外をキャッチして処理する必要はありません。 java.lang.RuntimeException(java.lang.RuntimeExceptionはjava.lang.Exceptionを継承します)。

自動ロールバック

    @Transactional(rollbackFor = Exception.class)
    public void asyncJob() throws Exception {
        success();
        //もし、データベースの操作を行うexceptionメソッドが例外をスローする場合、
        //success()メソッドでのデータベースの操作はロールバックされます。
        exception();
    }

手動ロールバック

    @Transactional(rollbackFor = Exception.class)
    public void asyncJob() {
        success();
        try {
            exception();
        } catch (Exception e) {
            e.printStackTrace();
            //手動ロールバック
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

一部ロールバック

    @Transactional(rollbackFor = Exception.class)
    public void asyncJob() {
        success();
        //ロールバック ポイントを設定し、次の例外のみをロールバックします
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        try {
            exception();
        } catch (Exception e) {
            e.printStackTrace();
            //savePoint へのロールバック
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
        }
    }

コメント

タイトルとURLをコピーしました