🖲️
Micronaut + jOOQでトランザクション管理
- Micronaut: 2.3.1
- jOOQ: 3.14.7
- Kotlin: 1.4.21
使用するテーブル
customerテーブル -> customer_detailテーブルの順でINSERTする処理で試す。
トランザクション管理なし
customer_detailテーブルのINSERTに失敗した場合に、先にINSERTしたcustomerテーブルはロールバックされない。
@Singleton
class CustomersService(
private val dslContext: DSLContext
) {
fun add(name: String) {
val id = Random.nextInt()
dslContext
.insertInto(CUSTOMER, CUSTOMER.ID, CUSTOMER.CREATED_AT)
.values(id, LocalDateTime.now())
.execute()
dslContext
.insertInto(CUSTOMER_DETAIL, CUSTOMER_DETAIL.CUSTOMER_ID, CUSTOMER_DETAIL.NAME, CUSTOMER_DETAIL.CREATED_AT)
.values(id, name, LocalDateTime.now())
.execute()
}
}
DSLContex#transactionを使用する
こちらは期待通りトランザクション管理される。
@Singleton
class CustomerService(
private val dslContext: DSLContext
) {
fun add(name: String) {
dslContext.transaction { c ->
val id = Random.nextInt()
DSL.using(c)
.insertInto(CUSTOMER, CUSTOMER.ID, CUSTOMER.CREATED_AT)
.values(id, LocalDateTime.now())
.execute()
DSL.using(c)
.insertInto(
CUSTOMER_DETAIL,
CUSTOMER_DETAIL.CUSTOMER_ID,
CUSTOMER_DETAIL.NAME,
CUSTOMER_DETAIL.CREATED_AT
)
.values(id, name, LocalDateTime.now())
.execute()
}
}
}
@TransactionalAdviceを使用する
TransactionalAdviceアノテーションを利用してトランザクション管理ができる。
SpringのTransactionalアノテーションと同様と考えればOK。
Gradleを使用してる場合、dependenciesに以下を追加する。
dependencies {
...
implementation 'io.micronaut.data:micronaut-data-tx'
}
TransactionalAdviceアノテーションを使用する場合はclassとメソッドをopenにする必要がある。
なお読み取り専用のReadOnlyアノテーションも用意されている。
@Singleton
open class CustomersService(
private val dslContext: DSLContext
) {
@TransactionalAdvice
open fun add(name: String) {
val id = Random.nextInt()
dslContext
.insertInto(CUSTOMER, CUSTOMER.ID, CUSTOMER.CREATED_AT)
.values(id, LocalDateTime.now())
.execute()
dslContext
.insertInto(CUSTOMER_DETAIL, CUSTOMER_DETAIL.CUSTOMER_ID, CUSTOMER_DETAIL.NAME, CUSTOMER_DETAIL.CREATED_AT)
.values(id, name, LocalDateTime.now())
.execute()
}
}
Discussion