カテゴリ: Spring 更新日: 2026/02/07

Springのトランザクション例外とロールバック完全ガイド!初心者でもわかるrollbackFor/noRollbackForの使い方

トランザクション例外とロールバック:rollbackFor/noRollbackForの設計
トランザクション例外とロールバック:rollbackFor/noRollbackForの設計

教材紹介 Spring Boot 学習のおすすめ教材

Spring Bootを使ったWebアプリケーション開発を、 環境構築から実践まで一通り学びたい方には、 定評のある入門書が参考になります。

Spring Boot 3 プログラミング入門をAmazonで見る

※ Amazon広告リンク

先生と生徒の会話形式で理解しよう

生徒

「Spring Bootでトランザクションを使ってるんですが、例外が発生してもロールバックされないことがあります。なぜですか?」

先生

「Springのトランザクション管理では、どの例外でロールバックするかを明示的に指定できるんですよ。」

生徒

「なるほど…。どうやって設定するんですか?」

先生

「それでは、rollbackFornoRollbackForの使い方について、具体例を交えて解説していきましょう!」

1. Springのトランザクションとは何か?

1. Springのトランザクションとは何か?
1. Springのトランザクションとは何か?

Spring FrameworkやSpring Bootを使ったJavaアプリケーション開発では、データベース処理をトランザクションで管理することが非常に重要です。トランザクションは、複数の処理をひとまとまりとして実行し、すべて成功したときだけコミット(確定)し、エラーが起きたときにはロールバック(取り消し)することで、データの整合性を保ちます。

Springでは@Transactionalアノテーションを使うことで、トランザクション制御を簡単に実現できます。


@Transactional
public void registerUser(User user) {
    userRepository.save(user);
    sendWelcomeMail(user);
}

2. 例外とロールバックの関係とは?

2. 例外とロールバックの関係とは?
2. 例外とロールバックの関係とは?

Springのトランザクション管理では、実行中に例外が発生するとロールバックされるのが基本です。ただし、すべての例外でロールバックされるわけではなく、Springは「デフォルトでRuntimeExceptionとError」が発生したときのみロールバックを行います。Exception(特にChecked Exception)がスローされても、ロールバックされないケースがあるのです。

これを理解せずに開発すると、「なぜかエラーが起きてるのにデータが保存されたまま…」という困った状況になります。

3. rollbackForで例外を指定する方法

3. rollbackForで例外を指定する方法
3. rollbackForで例外を指定する方法

ロールバックしたい例外がRuntimeException以外の場合、@TransactionalアノテーションのrollbackFor属性を使って、対象の例外クラスを指定できます。


@Transactional(rollbackFor = CustomCheckedException.class)
public void processPayment(Payment payment) throws CustomCheckedException {
    paymentService.withdraw(payment);
    throw new CustomCheckedException("処理中に例外が発生しました");
}

上記のように、CustomCheckedExceptionをスローしたときにもトランザクションがロールバックされるようになります。

4. noRollbackForでロールバックしない例外を指定

4. noRollbackForでロールバックしない例外を指定
4. noRollbackForでロールバックしない例外を指定

逆に、「この例外ではロールバックさせたくない」というケースでは、noRollbackFor属性を使います。例えば、バリデーションエラーや通知送信の失敗など、処理は続けたいけど記録は残したいといったときに使います。


@Transactional(noRollbackFor = NotificationException.class)
public void notifyUser(User user) {
    userRepository.save(user);
    throw new NotificationException("通知に失敗しました");
}

このようにすれば、NotificationExceptionが発生してもデータベースへの保存処理はロールバックされずにコミットされます。

5. rollbackForClassName/noRollbackForClassNameの活用

5. rollbackForClassName/noRollbackForClassNameの活用
5. rollbackForClassName/noRollbackForClassNameの活用

Springではクラス名(文字列)で例外を指定するrollbackForClassNamenoRollbackForClassNameもあります。これは動的に例外クラスが決まるケースや、依存関係の関係で直接クラスを指定できない場合に役立ちます。


@Transactional(rollbackForClassName = "com.example.exception.ExternalApiException")
public void callExternalService() throws Exception {
    throw new ExternalApiException("外部APIの呼び出しに失敗");
}

6. 複数の例外を指定する方法

6. 複数の例外を指定する方法
6. 複数の例外を指定する方法

複数の例外に対してロールバックや非ロールバックの設定をするには、カンマ区切りで配列として指定します。


@Transactional(
    rollbackFor = {IOException.class, SQLException.class},
    noRollbackFor = {ValidationException.class}
)
public void executeTask() throws IOException, SQLException {
    // 複雑な業務処理
}

7. 注意点:例外を握りつぶすとロールバックされない

7. 注意点:例外を握りつぶすとロールバックされない
7. 注意点:例外を握りつぶすとロールバックされない

メソッド内で例外をキャッチして処理してしまうと、Springはロールバックのトリガーとして例外を検出できなくなります。その結果、エラーが発生しているのにトランザクションがコミットされてしまう危険があります。


@Transactional
public void updateData() {
    try {
        riskyService.run();
    } catch (RuntimeException ex) {
        System.out.println("エラーをログに出力: " + ex.getMessage());
    }
}

上記のコードでは、例外がキャッチされてしまうため、ロールバックは起きません。どうしてもキャッチする必要がある場合は、再スローするか、明示的にTransactionAspectSupport.currentTransactionStatus().setRollbackOnly()を呼びましょう。

8. 実務での設計ポイントとリカバリ戦略

8. 実務での設計ポイントとリカバリ戦略
8. 実務での設計ポイントとリカバリ戦略

トランザクション例外処理の設計では、どのような例外でロールバックすべきか、業務要件に基づいて明確に設計することが重要です。特に外部システムとの連携や非同期処理などが絡む場合には、柔軟な例外制御が求められます。

例えば以下のようなルールを設けておくと、設計が安定します。

  • 業務エラー(ユーザー入力ミスなど)→ noRollbackFor
  • システムエラー(DB障害、ネットワーク断)→ rollbackFor
  • 外部APIの一時的失敗 → リトライ戦略と組み合わせ

9. 例外のカスタム設計とベストプラクティス

9. 例外のカスタム設計とベストプラクティス
9. 例外のカスタム設計とベストプラクティス

アプリケーションで扱う例外は、独自の例外クラスとして明確に定義しておくと、rollbackFornoRollbackForの指定がしやすくなります。また、例外の継承関係を整理しておくことで、意図しないロールバックの防止にもつながります。


public class BusinessException extends Exception {
    public BusinessException(String message) {
        super(message);
    }
}

このような例外クラスを設けることで、@Transactional(rollbackFor = BusinessException.class)のように明示的な制御が可能になります。

カテゴリの一覧へ
新着記事
New1
Spring
SpringDataJPAのJPAクエリメソッド「And」の使い方を完全ガイド!初心者向け解説
更新記事
New2
Spring
SpringDataJPAのJPAクエリメソッド「Distinct」の使い方を完全ガイド!初心者向け解説
更新記事
New3
Java
JavaのScannerクラスとnextメソッドの使い方を徹底解説!初心者でもわかる入力処理
更新記事
New4
Thymeleaf
Thymeleafのth:lang属性を完全解説!初心者でもわかる国際化対応の方法
更新記事
人気記事
No.1
Java&Spring記事人気No1
Spring
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Servlet
JavaのHttpSessionを徹底解説!初心者でもわかるセッション管理の基本
No.3
Java&Spring記事人気No3
Spring
Springの@Componentアノテーションの使い方を徹底解説!初心者でもわかるSpring Boot入門
No.4
Java&Spring記事人気No4
JSP
JSPの基本タグ一覧と使い方まとめ!実務で使えるタグを紹介
No.5
Java&Spring記事人気No5
Spring
Spring Data JPA入門!findAll()やfindBy**()の使い方などデータベース操作の基礎を学ぶ
No.6
Java&Spring記事人気No6
Spring
Spring BootのMultipartFile入門:ファイルアップロード・ダウンロードの実装方法と制限設定
No.7
Java&Spring記事人気No7
Spring
Springの@Serviceアノテーションの使い方を徹底解説!初心者でもわかるSpring フレームワーク入門
No.8
Java&Spring記事人気No8
Spring
SpringのModelクラスの使い方を完全ガイド!初心者でも安心

💻 作業効率アップに

長時間のコーディングでも疲れにくい♪ 静音ワイヤレスマウス

Logicool Signature M750 を見る

※ Amazon広告リンク