TL;DR
-
TransactionalOperator.transactional
を使うと簡単- 処理の中での
suspend
関数呼び出しはmono
関数でラップするのが簡単
- 処理の中での
やり方
サンプルコードは以下の通りです。
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.reactor.awaitSingle
import kotlinx.coroutines.reactor.mono
import org.springframework.stereotype.Component
import org.springframework.transaction.reactive.TransactionalOperator
@Component
class TransactionOperation(private val transactionalOperator: TransactionalOperator) {
// 中にそのまま処理を書く場合
suspend fun operation() {
transactionalOperator
.transactional(
mono {
/* ここにやりたい処理(DBアクセスを行うsuspend関数の呼び出しなど)を書く */
}
).awaitSingle()
}
// 外から処理を渡す場合
suspend operator fun <T> invoke(block: suspend CoroutineScope.() -> T): T = transactionalOperator
.transactional(mono(block = block))
.awaitSingle()
}
「外から処理を渡す場合」の利用例
transactionOperation {
/* ここにやりたい処理(DBアクセスを行うsuspend関数の呼び出しなど)を書く */
}
以下、このコードに関する解説を書きます。
TransactionalOperatorの取得について
TransactionalOperator
は、自分の環境ではAutowire
して利用できました。
また、ReactiveTransactionManager
から生成することもできます。
内部処理の書き方について
TransactionalOperator
を用いた処理は、低レベルAPI
に触れずに済む分Mono
/Flux
を渡すやりの方が扱いやすいと思います。
特に「外から処理を渡す場合」として紹介した方法は、普通にsuspend
関数を書くのと同じように利用することができるため、扱いやすいです。