カテゴリ: Spring 更新日: 2025/11/14

Springの@Transactional徹底解説!トランザクションの伝播・分離レベル・タイムアウトの基本

トランザクション入門:@Transactional の伝播・分離レベル・タイムアウト
トランザクション入門:@Transactional の伝播・分離レベル・タイムアウト

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

生徒

「Springの@Transactionalって、どうやって使えばいいんですか?トランザクションって正直難しそうで…」

先生

「確かに最初は戸惑いますよね。でも実は、@Transactionalを使えば、データベースの整合性を保つ処理が簡単に実現できますよ。」

生徒

「伝播とか分離レベルとか、設定項目もたくさんあって不安です…」

先生

「それなら、初心者でも理解しやすいように、基礎から丁寧に説明していきましょう!」

1. Springにおけるトランザクション管理の基本

1. Springにおけるトランザクション管理の基本
1. Springにおけるトランザクション管理の基本

トランザクションとは、データベースへの操作をひとつのまとまりとして扱い、すべて成功したときだけ確定し、失敗したときには元に戻す仕組みです。Springでは、@Transactionalアノテーションを使うことで、自動的にトランザクション管理が行えるようになります。

これにより、複数の処理を安全にまとめて実行し、データの整合性を保つことができます。たとえば、ユーザー登録時にユーザー情報と履歴を同時に保存する処理などが該当します。

2. @Transactionalの基本的な使い方

2. @Transactionalの基本的な使い方
2. @Transactionalの基本的な使い方

まずは基本の書き方を見てみましょう。@Transactionalをメソッドやクラスに付けるだけで、トランザクションが自動的に開始・コミット・ロールバックされます。


@Service
public class UserService {

    @Transactional
    public void registerUser(User user) {
        userRepository.save(user);
        logRepository.save(new Log("ユーザー登録"));
    }
}

この例では、ユーザーとログの登録が両方成功した場合のみ、データベースに反映されます。どちらかで例外が発生したら、自動的にロールバックされるのが特徴です。

3. トランザクションの伝播(propagation)の種類と意味

3. トランザクションの伝播(propagation)の種類と意味
3. トランザクションの伝播(propagation)の種類と意味

@Transactionalには、propagation(伝播)という設定があります。これは「すでにトランザクションが存在している場合に、どう振る舞うか」を指定します。

代表的な伝播タイプ:

  • REQUIRED(デフォルト):既存のトランザクションがあれば参加、なければ新規作成
  • REQUIRES_NEW:常に新しいトランザクションを開始(既存は一時中断)
  • MANDATORY:既存トランザクションがないと例外
  • NEVER:トランザクションがあると例外
  • NESTED:ネストされたトランザクション(JDBCやDBによる)

たとえばログだけ別トランザクションにしたいときにはREQUIRES_NEWを使います。


@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveLog(Log log) {
    logRepository.save(log);
}

4. 分離レベル(isolation)の基本と使いどころ

4. 分離レベル(isolation)の基本と使いどころ
4. 分離レベル(isolation)の基本と使いどころ

分離レベルは、同時に実行されるトランザクション同士のデータの見え方を制御します。具体的には、読み取り時に他のトランザクションの未確定データを見えるようにするかどうかです。

Springの@Transactionalでは、以下の分離レベルが指定できます:

  • DEFAULT:データベースのデフォルト設定に従う
  • READ_UNCOMMITTED:未コミットデータも見える(ダーティリード)
  • READ_COMMITTED:コミット済みのデータのみ(一般的)
  • REPEATABLE_READ:同一トランザクション内では同じ結果が保証される
  • SERIALIZABLE:完全に直列化、最も安全だが最も重い

@Transactional(isolation = Isolation.READ_COMMITTED)
public void readData() {
    // 安全な読み取り処理
}

基本的にはREAD_COMMITTEDREPEATABLE_READが使われます。

5. タイムアウト(timeout)の設定と注意点

5. タイムアウト(timeout)の設定と注意点
5. タイムアウト(timeout)の設定と注意点

トランザクションが長時間ロックを保持しないように制限できるのがtimeout設定です。秒数で指定し、指定時間内に処理が終わらないとTransactionTimedOutExceptionがスローされます。


@Transactional(timeout = 5)
public void longProcess() {
    // 5秒以内に完了しないと例外
}

タイムアウトを設定することで、ロック待ちによる遅延や、パフォーマンス劣化を防ぐことができます。

6. rollbackFor属性による例外制御

6. rollbackFor属性による例外制御
6. rollbackFor属性による例外制御

@Transactionalでは、どの例外が発生したときにロールバックするかも指定できます。通常はRuntimeException系でロールバックされますが、それ以外の例外でもロールバックしたい場合はrollbackForを使います。


@Transactional(rollbackFor = { IOException.class, SQLException.class })
public void riskyMethod() throws IOException {
    // 例外発生時にロールバック
}

逆に、ロールバックさせたくない例外がある場合はnoRollbackForも指定できます。

7. トランザクションの確認とログの出力方法

7. トランザクションの確認とログの出力方法
7. トランザクションの確認とログの出力方法

Springでは、トランザクションの開始・コミット・ロールバックのタイミングをログで確認できます。設定ファイルでログレベルをDEBUGにすると、詳細な情報が出力されます。


logging.level.org.springframework.transaction=DEBUG

これにより、思った通りにトランザクションが制御されているかを確認できます。特に分離レベルや伝播に関するバグを追うときに有効です。

カテゴリの一覧へ
新着記事
SpringのBindingResultを完全ガイド!初心者でもわかる入力チェックとエラー処理
Spring Securityでフォームログインを実装!ログイン・ログアウト・Remember-Meの設定方法まとめ
Javaの@Validアノテーションを徹底解説!初心者でもわかる入力値検証の基本
JavaのPart.getContentTypeメソッドの使い方を解説!初心者向けファイルタイプの確認方法
人気記事
No.1
Java&Spring記事人気No1
JavaのExceptionクラスを完全解説!初心者でも理解できる例外処理の基本
No.2
Java&Spring記事人気No2
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.3
Java&Spring記事人気No3
JavaのDateクラスの使い方を完全ガイド!初心者でもわかる日付操作
No.4
Java&Spring記事人気No4
Javaのラムダ式anyMatchの使い方:containsやList検索の実践テクニック
No.5
Java&Spring記事人気No5
Javaのラムダ式でListを抽出&変換!filterとmapでスマートに操作
No.6
Java&Spring記事人気No6
JSPで使えるJavaコードの書き方を徹底解説!初心者向けルールと制限ポイント
No.7
Java&Spring記事人気No7
Spring BootのJakarta移行ガイド!初心者向けjavax→jakarta変更ポイント徹底解説
No.8
Java&Spring記事人気No8
Javaのcountの使い方を完全ガイド!ラムダ式で件数カウントの定石をマスターしよう