LoginSignup
3

More than 3 years have passed since last update.

【Java・SpringBoot】@Transactionの設定まとめ

Posted at

ホーム画面からユーザー一覧画面に遷移し、ユーザーの詳細を表示するアプリケーションを作成して、Spring JDBCの使い方について学びます⭐️
前回、前々回では宣言的/明示的トランザクションを学びました。
今回は宣言的トランザクション(@Transaction)の設定についてのまとめです^^
構成は前回/前々回の記事を参考にしてください

⭐️前回/前々回の記事
Java・SpringBoot】宣言的トランザクション処理(SpringBootアプリケーション実践編20)
【Java・SpringBoot】明示的トランザクション処理(SpringBootアプリケーション実践編21)

@Transactionアノテーションの設定

属性 説明
value 複数のトランザクションマネージャーを使用する場合、利用するトランザクションマネージャーのQualifierを指定する。
デフォルトでは省略可能(transactionManagerも同じ)

propagation トランザクションの伝播レベルを指定
isolation トランザクションの分離レベルを指定
timeout トランザクションのタイムアウト時間(秒)を指定。
デフォルトは-1(使用するデータベースの仕様や設定に依存)
readOnly トランザクションの読取専用フラグを指定。
デフォルトはfalse(読取専用ではない)
rollbackFor トランザクションのロールバック対象とする例外クラスのリストを指定。
デフォルトはRuntimeException(非検査例外)がロールバック対象。
rollbackForClassName トランザクションのロールバック対象とする例外クラス名のリストを指定。
デフォルトは空(指定なし)
noRollbackFor トランザクションのコミット対象とする例外クラスのリストを指定。
デフォルトは空(指定なし)
noRollbackForClassName トランザクションのコミット対象とする例外クラス名のリストを指定。
デフォルトは空(指定なし)

トランザクションの独立性(分離性)

  • トランザクションを複数同時に実行しても、正常な処理をしなければならないこと
  • 複数ユーザーがアプリケーションを使う場合、トランザクションは複数存在する
  • →同じデータを参照する際には注意が必要!
    • ex: トランザクションA、Bが同時に口座の情報を読み取り、同時に更新した場合に、データ不整合になってしまう
    • トランザクションAが終了するまで、トランザクションBは待機しないといけない
  • Springの分離レベルで独立性のレベルを指定

トランザクション分離レベル

  • トランザクションの分離レベルは、isolation属性に以下の値を指定
分離レベル 説明
DEFAULT 利用するデータベースのデフォルトの分離レベルを利用
READ_UNCOMMITTED 他のトランザクションが、まだコミットしていないデータを読み出せる
変更データがロールバックされた場合、次のトランザクションでは無効な行データが検索される
READ_COMMITTED 他のトランザクションがコミットしていないデータは読み出せない
REPEATABLE_READ トランザクション内で、複数回データを読み込んだ場合、他のトランザクションが途中でデータを変更しても、同じ値が読み込まれる
SERIALIZABLE トランザクションを順番に処理

独立性における代表的な問題

  • ダーティリード
    • 他のトランザクションが変更したが、まだコミットしていないデータを読み取ってしまい、誤ったデータを読み取ってしまう
  • ノンリピータブルリード
    • トランザクションの中で、何回も同じデータを読み取るときに、他のトランザクションがデータを更新してしまうと、途中から違う値を読み取ってしまう
  • ファントムリード
    • トランザクションの中で、何回も同じデータを読み取ると、他のトランザクションが新しくデータを追加すると途中から処理対象のレコードが増える

分離レベルが問題を解決できるかどうか

分離レベル ダーティリード ノンリピータブルリード ファントムリード
READ_UNCOMMITTED × × ×
READ_COMMITTED × ×
REPEATABLE_READ ×
SERIALIZABLE

トランザクションの伝播レベル

  • トランザクションを新たに作成し、開始するかどうかの設定
  • 特に、サービスクラスから別のサービスクラスを呼び出す場合、トランザクションを開始するのか、既存トランザクションに参加するのかを設定することができる
    • トランザクションを直接呼ぶときは、トランザクション開始する・例外を投げる・作成しないのどれに当てはまるか、
    • 間接的に呼ぶときは、参加する・開始する・例外を投げる・作成しない、のどれに当てはまるか、を検討する
伝播レベル 説明
REQUIRED デフォルト設定。トランザクションが存在しない場合、新規にトランザクションを開始。すでに存在する場合はそのトランザクションを利用
QUIRES_NEW 必ず新規のトランザクションを作成
MANDATORY すでにトランザクションが存在することを前提にし、トランザクションが存在しない場合、例外発生
すでに存在する場合は、そのトランザクションを利用
NEVER トランザクションを使用しない。
すでにトランザクションが存在する場合は例外が発生
NOT_SUPPORTED トランザクションを使用しない
すでにトランザクションが存在する場合はそのトランザクションを一時停止し、トランザクションを使用せずに処理を実行後、停止していたトランザクションを再開
SUPPORTS トランザクションが存在しない場合、トランザクション作成しない
既に存在する場合は、そのトランザクションを利用
NESTED ネストしたトランザクションを作成
トランザクションが存在しない場合、新規にトランザクションを開始し、すでに存在する場合はそのトランザクションを利用するが、その部分だけネストしたトランザクションのように処理

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3