public class R2dbcTransactionManager
extends org.springframework.transaction.reactive.AbstractReactiveTransactionManager
implements org.springframework.beans.factory.InitializingBean
ReactiveTransactionManager implementation
for a single R2DBC ConnectionFactory. This class is capable of working
in any environment with any R2DBC driver, as long as the setup uses a
ConnectionFactory as its Connection factory mechanism.
Binds a R2DBC Connection from the specified ConnectionFactory
to the current subscriber context, potentially allowing for one context-bound
Connection per ConnectionFactory.
Note: The ConnectionFactory that this transaction manager operates
on needs to return independent Connections. The Connections
typically come from a connection pool but the ConnectionFactory must not
return specifically scoped or constrained Connections. This transaction
manager will associate Connection with context-bound transactions,
according to the specified propagation behavior. It assumes that a separate,
independent Connection can be obtained even during an ongoing transaction.
Application code is required to retrieve the R2DBC Connection via
ConnectionFactoryUtils.getConnection(ConnectionFactory)
instead of a standard R2DBC-style ConnectionFactory.create() call.
Spring classes such as DatabaseClient use this strategy implicitly.
If not used in combination with this transaction manager, the
ConnectionFactoryUtils lookup strategy behaves exactly like the native
ConnectionFactory lookup; it can thus be used in a portable fashion.
Alternatively, you can allow application code to work with the lookup pattern
ConnectionFactory.create(), for example for code not aware of Spring.
In that case, define a TransactionAwareConnectionFactoryProxy for your
target ConnectionFactory, and pass that proxy ConnectionFactory
to your DAOs which will automatically participate in Spring-managed transactions
when accessing it.
| Constructor and Description |
|---|
R2dbcTransactionManager()
Create a new
R2dbcTransactionManager instance. |
R2dbcTransactionManager(ConnectionFactory connectionFactory)
Create a new
R2dbcTransactionManager instance. |
| Modifier and Type | Method and Description |
|---|---|
void |
afterPropertiesSet() |
protected Duration |
determineTimeout(org.springframework.transaction.TransactionDefinition definition)
Determine the actual timeout to use for the given definition.
|
protected reactor.core.publisher.Mono<Void> |
doBegin(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager,
Object transaction,
org.springframework.transaction.TransactionDefinition definition) |
protected reactor.core.publisher.Mono<Void> |
doCleanupAfterCompletion(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager,
Object transaction) |
protected reactor.core.publisher.Mono<Void> |
doCommit(org.springframework.transaction.reactive.TransactionSynchronizationManager TransactionSynchronizationManager,
org.springframework.transaction.reactive.GenericReactiveTransaction status) |
protected Object |
doGetTransaction(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager) |
protected reactor.core.publisher.Mono<Void> |
doResume(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager,
Object transaction,
Object suspendedResources) |
protected reactor.core.publisher.Mono<Void> |
doRollback(org.springframework.transaction.reactive.TransactionSynchronizationManager TransactionSynchronizationManager,
org.springframework.transaction.reactive.GenericReactiveTransaction status) |
protected reactor.core.publisher.Mono<Void> |
doSetRollbackOnly(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager,
org.springframework.transaction.reactive.GenericReactiveTransaction status) |
protected reactor.core.publisher.Mono<Object> |
doSuspend(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager,
Object transaction) |
ConnectionFactory |
getConnectionFactory()
Return the R2DBC
ConnectionFactory that this instance manages transactions for. |
boolean |
isEnforceReadOnly()
Return whether to enforce the read-only nature of a transaction through an
explicit statement on the transactional connection.
|
protected boolean |
isExistingTransaction(Object transaction) |
protected ConnectionFactory |
obtainConnectionFactory()
Obtain the
ConnectionFactory for actual use. |
protected reactor.core.publisher.Mono<Void> |
prepareTransactionalConnection(Connection con,
org.springframework.transaction.TransactionDefinition definition)
Prepare the transactional
Connection right after transaction begin. |
protected reactor.core.publisher.Mono<Void> |
prepareTransactionalConnection(Connection con,
org.springframework.transaction.TransactionDefinition definition,
Object transaction)
Deprecated.
in favor of
prepareTransactionalConnection(Connection, TransactionDefinition)
since this variant gets called too early (before transaction begin) for read-only customization |
protected IsolationLevel |
resolveIsolationLevel(int isolationLevel)
Resolve the isolation level constant to a R2DBC
IsolationLevel. |
void |
setConnectionFactory(ConnectionFactory connectionFactory)
Set the R2DBC
ConnectionFactory that this instance should manage transactions
for. |
void |
setEnforceReadOnly(boolean enforceReadOnly)
Specify whether to enforce the read-only nature of a transaction (as indicated by
TransactionDefinition.isReadOnly()) through an explicit statement on the
transactional connection: "SET TRANSACTION READ ONLY" as understood by Oracle,
MySQL and Postgres. |
protected RuntimeException |
translateException(String task,
R2dbcException ex)
Translate the given R2DBC commit/rollback exception to a common Spring exception to propagate
from the
AbstractReactiveTransactionManager.commit(org.springframework.transaction.ReactiveTransaction)/AbstractReactiveTransactionManager.rollback(org.springframework.transaction.ReactiveTransaction) call. |
public R2dbcTransactionManager()
R2dbcTransactionManager instance.
A ConnectionFactory has to be set to be able to use it.public R2dbcTransactionManager(ConnectionFactory connectionFactory)
R2dbcTransactionManager instance.connectionFactory - the R2DBC ConnectionFactory to manage transactions forpublic void setConnectionFactory(@Nullable
ConnectionFactory connectionFactory)
ConnectionFactory that this instance should manage transactions
for. This will typically be a locally defined ConnectionFactory, for example
an R2DBC connection pool.
The ConnectionFactory passed in here needs to return independent
Connections. The Connections typically come from a connection
pool but the ConnectionFactory must not return specifically scoped or
constrained Connections.
@Nullable public ConnectionFactory getConnectionFactory()
ConnectionFactory that this instance manages transactions for.protected ConnectionFactory obtainConnectionFactory()
ConnectionFactory for actual use.ConnectionFactory (never null)IllegalStateException - in case of no ConnectionFactory setpublic void setEnforceReadOnly(boolean enforceReadOnly)
TransactionDefinition.isReadOnly()) through an explicit statement on the
transactional connection: "SET TRANSACTION READ ONLY" as understood by Oracle,
MySQL and Postgres.
The exact treatment, including any SQL statement executed on the connection,
can be customized through prepareTransactionalConnection(io.r2dbc.spi.Connection, org.springframework.transaction.TransactionDefinition, java.lang.Object).
public boolean isEnforceReadOnly()
setEnforceReadOnly(boolean)public void afterPropertiesSet()
afterPropertiesSet in interface org.springframework.beans.factory.InitializingBeanprotected Object doGetTransaction(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager) throws org.springframework.transaction.TransactionException
doGetTransaction in class org.springframework.transaction.reactive.AbstractReactiveTransactionManagerorg.springframework.transaction.TransactionExceptionprotected boolean isExistingTransaction(Object transaction)
isExistingTransaction in class org.springframework.transaction.reactive.AbstractReactiveTransactionManagerprotected reactor.core.publisher.Mono<Void> doBegin(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager, Object transaction, org.springframework.transaction.TransactionDefinition definition) throws org.springframework.transaction.TransactionException
doBegin in class org.springframework.transaction.reactive.AbstractReactiveTransactionManagerorg.springframework.transaction.TransactionExceptionprotected Duration determineTimeout(org.springframework.transaction.TransactionDefinition definition)
definition - the transaction definitionTransactionDefinition.getTimeout()protected reactor.core.publisher.Mono<Object> doSuspend(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager, Object transaction) throws org.springframework.transaction.TransactionException
doSuspend in class org.springframework.transaction.reactive.AbstractReactiveTransactionManagerorg.springframework.transaction.TransactionExceptionprotected reactor.core.publisher.Mono<Void> doResume(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager, @Nullable Object transaction, Object suspendedResources) throws org.springframework.transaction.TransactionException
doResume in class org.springframework.transaction.reactive.AbstractReactiveTransactionManagerorg.springframework.transaction.TransactionExceptionprotected reactor.core.publisher.Mono<Void> doCommit(org.springframework.transaction.reactive.TransactionSynchronizationManager TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction status) throws org.springframework.transaction.TransactionException
doCommit in class org.springframework.transaction.reactive.AbstractReactiveTransactionManagerorg.springframework.transaction.TransactionExceptionprotected reactor.core.publisher.Mono<Void> doRollback(org.springframework.transaction.reactive.TransactionSynchronizationManager TransactionSynchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction status) throws org.springframework.transaction.TransactionException
doRollback in class org.springframework.transaction.reactive.AbstractReactiveTransactionManagerorg.springframework.transaction.TransactionExceptionprotected reactor.core.publisher.Mono<Void> doSetRollbackOnly(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager, org.springframework.transaction.reactive.GenericReactiveTransaction status) throws org.springframework.transaction.TransactionException
doSetRollbackOnly in class org.springframework.transaction.reactive.AbstractReactiveTransactionManagerorg.springframework.transaction.TransactionExceptionprotected reactor.core.publisher.Mono<Void> doCleanupAfterCompletion(org.springframework.transaction.reactive.TransactionSynchronizationManager synchronizationManager, Object transaction)
doCleanupAfterCompletion in class org.springframework.transaction.reactive.AbstractReactiveTransactionManager@Deprecated protected reactor.core.publisher.Mono<Void> prepareTransactionalConnection(Connection con, org.springframework.transaction.TransactionDefinition definition, Object transaction)
prepareTransactionalConnection(Connection, TransactionDefinition)
since this variant gets called too early (before transaction begin) for read-only customizationConnection right before transaction begin.protected reactor.core.publisher.Mono<Void> prepareTransactionalConnection(Connection con, org.springframework.transaction.TransactionDefinition definition)
Connection right after transaction begin.
The default implementation executes a "SET TRANSACTION READ ONLY" statement if the
"enforceReadOnly" flag is set to true and the
transaction definition indicates a read-only transaction.
The "SET TRANSACTION READ ONLY" is understood by Oracle, MySQL and Postgres and may work with other databases as well. If you'd like to adapt this treatment, override this method accordingly.
con - the transactional R2DBC Connectiondefinition - the current transaction definitionsetEnforceReadOnly(boolean)@Nullable protected IsolationLevel resolveIsolationLevel(int isolationLevel)
IsolationLevel. If you'd like to extend isolation level translation for vendor-specific
IsolationLevels, override this method accordingly.isolationLevel - the isolation level to translate.null if not resolvable or the isolation level
should remain default.TransactionDefinition.getIsolationLevel()protected RuntimeException translateException(String task, R2dbcException ex)
AbstractReactiveTransactionManager.commit(org.springframework.transaction.ReactiveTransaction)/AbstractReactiveTransactionManager.rollback(org.springframework.transaction.ReactiveTransaction) call.task - the task description (commit or rollback).ex - the SQLException thrown from commit/rollback.