概要
SpringBatchでTaskletを使ってトランザクション処理を書いていたのですが、
「あれ、commitされない…」という事象に当たったので解決方法を残しておきます
利用ライブラリ
- org.springframework.boot:spring-boot-starter-batch:2.3.5.RELEASE
- org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3
問題のコード
サンプルですが、@Transactional
を使ってトランザクション管理をしようとしています
Sample.java
@Transactional(rollbackFor = Throwable.class)
public class Sample {
// トランザクション処理を行うメソッド
public doTransaction {
// DBへのinsert, update, deleteなど
}
}
期待としてはdoTransaction
メソッド実行後にcommitが実行される
と思っていたのですが、実行されない…
解決方法
@Transactional
でpropagation = Propagation.REQUIRES_NEW
を設定すればOK!
@Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRES_NEW)
デフォルトではPropagation.REQUIRED
が設定されているのですが、
これは
- トランザクションがすでに存在すれば、そのトランザクションを利用
- 親のトランザクションが終了しないとcommitされない
- トランザクションが存在しなければ、新規に作成
という動作になる設定のようです。
(推測ですが)SpringBatchで生成した親トランザクションがいたので、そのトランザクションに吸収されていたようです。
Propagation.REQUIRES_NEW
を指定すると、既存のトランザクションの有無によらず、
新しいトランザクションが生成されるようになります😊