org.komapper.tx.context.r2dbc.ContextualR2dbcFlowTransactionOperator.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of komapper-tx-context-r2dbc Show documentation
Show all versions of komapper-tx-context-r2dbc Show documentation
Komapper Transaction Context for R2DBC
The newest version!
package org.komapper.tx.context.r2dbc
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onCompletion
import org.komapper.core.ThreadSafe
import org.komapper.tx.core.EmptyTransactionProperty
import org.komapper.tx.core.TransactionProperty
@ThreadSafe
interface ContextualR2dbcFlowTransactionOperator {
context(R2dbcContext)
fun required(
transactionProperty: TransactionProperty = EmptyTransactionProperty,
block: suspend context(R2dbcContext)
FlowCollector.() -> Unit,
): Flow
context(R2dbcContext)
fun requiresNew(
transactionProperty: TransactionProperty = EmptyTransactionProperty,
block: suspend context(R2dbcContext)
FlowCollector.() -> Unit,
): Flow
context(R2dbcContext)
suspend fun setRollbackOnly()
context(R2dbcContext)
suspend fun isRollbackOnly(): Boolean
}
internal class ContextualR2dbcFlowTransactionOperatorImpl(
private val transactionManager: ContextualR2dbcTransactionManager,
private val defaultTransactionProperty: TransactionProperty = EmptyTransactionProperty,
) : ContextualR2dbcFlowTransactionOperator {
context(R2dbcContext)
override fun required(
transactionProperty: TransactionProperty,
block: suspend context(R2dbcContext)
FlowCollector.() -> Unit,
): Flow {
return flow {
if (transactionManager.isActive()) {
block(this@R2dbcContext, this@flow)
} else {
val value = executeInNewTransaction(transactionProperty, block)
emitAll(value)
}
}
}
context(R2dbcContext)
override fun requiresNew(
transactionProperty: TransactionProperty,
block: suspend context(R2dbcContext)
FlowCollector.() -> Unit,
): Flow {
return flow {
val value = if (transactionManager.isActive()) {
val transactionContext = transactionManager.suspend()
val r2dbcContext = R2dbcContext(database, transactionOperator, flowTransactionOperator, transactionContext.transaction)
with(r2dbcContext) {
executeInNewTransaction(transactionProperty, block)
}.onCompletion {
transactionManager.resume()
}
} else {
executeInNewTransaction(transactionProperty, block)
}
emitAll(value)
}
}
context(R2dbcContext)
private suspend fun executeInNewTransaction(
transactionProperty: TransactionProperty,
block: suspend context(R2dbcContext)
FlowCollector.() -> Unit,
): Flow {
val transactionContext = transactionManager.begin(defaultTransactionProperty + transactionProperty)
val r2dbcContext = R2dbcContext(database, transactionOperator, flowTransactionOperator, transactionContext.transaction)
return flow {
with(r2dbcContext) {
kotlin.runCatching {
block(this@with, this@flow)
}.onSuccess {
if (transactionManager.isRollbackOnly()) {
transactionManager.rollback()
} else {
transactionManager.commit()
}
}.onFailure { cause ->
kotlin.runCatching {
transactionManager.rollback()
}.onFailure {
cause.addSuppressed(it)
}
}.getOrThrow()
}
}
}
context(R2dbcContext)
override suspend fun setRollbackOnly() {
transactionManager.setRollbackOnly()
}
context(R2dbcContext)
override suspend fun isRollbackOnly(): Boolean {
return transactionManager.isRollbackOnly()
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy