構成
- Spring-Boot 3.0.x
- Spring-JDBC (not Spring Data JDBC)
- jOOQ
- HikariCP
結論
jOOQのConfigurationオブジェクトの設定において、DataSourceをTransactionAwareDataSourceProxyでラップする。
var config = new DefaultConfiguration();
config.setDataSource( new TransactionAwareDataSourceProxy(dataSource) );
事例
@Transactionalアノテーションによるトランザクション制御をやりたい。
ログではinsert文が発行されているが、その後にDBに反映されていない。
publicメソッドに@Transactionalを設定、サービス起動時にそのアノテーションに関する処理が走ってることを確認。
HikariCP側ではAutoCommit=falseを設定。
結論の記述を行うことで解決。
ConfigurationにはConnectionProviderやら何やら他のDataSource設定方法もあるので、そちらを使う場合はそっちでDataSourceをラップしてやればいい。
雑記
TransactionAwareDataSourceProxyの説明を見ると分かるが、jOOQ以外でも他のフレームワーク入れた際にトランザクションがうまく機能しない時にとりあえず試すのがよさそう。参考に先人の記事も追加。
jOOQのトランザクション制御とSpringのトランザクション制御を混ぜるのはNGらしい。
かつSpring配下でjOOQのトランザクション制御を使うのも微妙っぽい。SpringTransactionProviderというのがそれを扱うものだが、githubのissueでいろいろ議論されていていまだにcloseされていないので、やりたい場合は最新の状況の確認が必要。
jOOQを使う時にはTransactionManagerでrollbackOnCommitFailure=falseにしたほうがいいらしい。(トランザクション内での例外が全てSQLExceptionなら不要かも。そうでない場合は例外時でもCommitされる)
参考
Craftsmen - jOOQ and Spring Transactions, without blockage
3rdパーティ製のDBアクセスライブラリをSpringのトランザクション管理下に参加させる方法