Polish reactive transaction mgmt documentation in reference manual
See gh-25030
This commit is contained in:
parent
7fbdc3ad11
commit
e1b2cafb33
|
|
@ -150,10 +150,13 @@ configuration file need to change (rather than your code).
|
|||
[[transaction-strategies]]
|
||||
=== Understanding the Spring Framework Transaction Abstraction
|
||||
|
||||
The key to the Spring transaction abstraction is the notion of a transaction
|
||||
strategy. A transaction strategy is defined by a `TransactionManager`, specifically
|
||||
the `org.springframework.transaction.PlatformTransactionManager` interface for
|
||||
imperative transaction management which the following listing shows:
|
||||
The key to the Spring transaction abstraction is the notion of a transaction strategy. A
|
||||
transaction strategy is defined by a `TransactionManager`, specifically the
|
||||
`org.springframework.transaction.PlatformTransactionManager` interface for imperative
|
||||
transaction management and the
|
||||
`org.springframework.transaction.ReactiveTransactionManager` interface for reactive
|
||||
transaction management. The following listing shows the definition of the
|
||||
`PlatformTransactionManager` API:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -189,8 +192,8 @@ This is primarily a service provider interface (SPI), although you can use it
|
|||
necessary. It is not tied to a lookup strategy, such as JNDI.
|
||||
`PlatformTransactionManager` implementations are defined like any other object (or bean)
|
||||
in the Spring Framework IoC container. This benefit alone makes Spring Framework
|
||||
transactions a worthwhile abstraction, even when you work with JTA. You can test transactional code
|
||||
much more easily than if it used JTA directly.
|
||||
transactions a worthwhile abstraction, even when you work with JTA. You can test
|
||||
transactional code much more easily than if it used JTA directly.
|
||||
|
||||
Again, in keeping with Spring's philosophy, the `TransactionException` that can be thrown
|
||||
by any of the `PlatformTransactionManager` interface's methods is unchecked (that
|
||||
|
|
@ -207,9 +210,9 @@ exists in the current call stack. The implication in this latter case is that, a
|
|||
Java EE transaction contexts, a `TransactionStatus` is associated with a thread of
|
||||
execution.
|
||||
|
||||
Spring Framework provides a transaction management abstraction for reactive applications
|
||||
that make use of reactive types or Kotlin Coroutines. The following listing
|
||||
shows the transaction strategy defined by
|
||||
As of Spring Framework 5.2, Spring also provides a transaction management abstraction for
|
||||
reactive applications that make use of reactive types or Kotlin Coroutines. The following
|
||||
listing shows the transaction strategy defined by
|
||||
`org.springframework.transaction.ReactiveTransactionManager`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
|
|
@ -240,10 +243,10 @@ shows the transaction strategy defined by
|
|||
}
|
||||
----
|
||||
|
||||
The reactive transaction manager is primarily a service provider interface (SPI),
|
||||
although you can use it <<transaction-programmatic-rtm, programmatically>> from your
|
||||
application code. Because `ReactiveTransactionManager` is an interface, it can
|
||||
be easily mocked or stubbed as necessary.
|
||||
The reactive transaction manager is primarily a service provider interface (SPI),
|
||||
although you can use it <<transaction-programmatic-rtm, programmatically>> from your
|
||||
application code. Because `ReactiveTransactionManager` is an interface, it can be easily
|
||||
mocked or stubbed as necessary.
|
||||
|
||||
The `TransactionDefinition` interface specifies:
|
||||
|
||||
|
|
@ -315,13 +318,13 @@ familiar, as they are common to all transaction APIs. The following listing show
|
|||
----
|
||||
|
||||
Regardless of whether you opt for declarative or programmatic transaction management in
|
||||
Spring, defining the correct `TransactionManager` implementation is absolutely
|
||||
essential. You typically define this implementation through dependency injection.
|
||||
Spring, defining the correct `TransactionManager` implementation is absolutely essential.
|
||||
You typically define this implementation through dependency injection.
|
||||
|
||||
`TransactionManager` implementations normally require knowledge of the
|
||||
environment in which they work: JDBC, JTA, Hibernate, and so on. The following examples
|
||||
show how you can define a local `PlatformTransactionManager` implementation (in this case,
|
||||
with plain JDBC.)
|
||||
`TransactionManager` implementations normally require knowledge of the environment in
|
||||
which they work: JDBC, JTA, Hibernate, and so on. The following examples show how you can
|
||||
define a local `PlatformTransactionManager` implementation (in this case, with plain
|
||||
JDBC.)
|
||||
|
||||
You can define a JDBC `DataSource` by creating a bean similar to the following:
|
||||
|
||||
|
|
@ -335,8 +338,8 @@ You can define a JDBC `DataSource` by creating a bean similar to the following:
|
|||
</bean>
|
||||
----
|
||||
|
||||
The related `PlatformTransactionManager` bean definition then has a reference to
|
||||
the `DataSource` definition. It should resemble the following example:
|
||||
The related `PlatformTransactionManager` bean definition then has a reference to the
|
||||
`DataSource` definition. It should resemble the following example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
|
|
@ -346,8 +349,8 @@ the `DataSource` definition. It should resemble the following example:
|
|||
----
|
||||
|
||||
If you use JTA in a Java EE container, then you use a container `DataSource`, obtained
|
||||
through JNDI, in conjunction with Spring's `JtaTransactionManager`. The following example shows what the JTA
|
||||
and JNDI lookup version would look like:
|
||||
through JNDI, in conjunction with Spring's `JtaTransactionManager`. The following example
|
||||
shows what the JTA and JNDI lookup version would look like:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
|
|
@ -378,21 +381,21 @@ NOTE: The preceding definition of the `dataSource` bean uses the `<jndi-lookup/>
|
|||
from the `jee` namespace. For more information see
|
||||
<<integration.adoc#xsd-schemas-jee, The JEE Schema>>.
|
||||
|
||||
You can also use easily Hibernate local transactions, as shown in the following
|
||||
examples. In this case, you need to define a Hibernate `LocalSessionFactoryBean`,
|
||||
which your application code can use to obtain Hibernate `Session` instances.
|
||||
You can also easily use Hibernate local transactions, as shown in the following examples.
|
||||
In this case, you need to define a Hibernate `LocalSessionFactoryBean`, which your
|
||||
application code can use to obtain Hibernate `Session` instances.
|
||||
|
||||
The `DataSource` bean definition is similar to the local JDBC example shown
|
||||
previously and, thus, is not shown in the following example.
|
||||
The `DataSource` bean definition is similar to the local JDBC example shown previously
|
||||
and, thus, is not shown in the following example.
|
||||
|
||||
NOTE: If the `DataSource` (used by any non-JTA transaction manager) is looked up through
|
||||
JNDI and managed by a Java EE container, it should be non-transactional, because the
|
||||
Spring Framework (rather than the Java EE container) manages the transactions.
|
||||
|
||||
The `txManager` bean in this case is of the `HibernateTransactionManager` type. In the
|
||||
same way as the `DataSourceTransactionManager` needs a reference to the `DataSource`,
|
||||
the `HibernateTransactionManager` needs a reference to the `SessionFactory`.
|
||||
The following example declares `sessionFactory` and `txManager` beans:
|
||||
same way as the `DataSourceTransactionManager` needs a reference to the `DataSource`, the
|
||||
`HibernateTransactionManager` needs a reference to the `SessionFactory`. The following
|
||||
example declares `sessionFactory` and `txManager` beans:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
|
|
@ -415,9 +418,9 @@ The following example declares `sessionFactory` and `txManager` beans:
|
|||
</bean>
|
||||
----
|
||||
|
||||
If you use Hibernate and Java EE container-managed JTA transactions, you
|
||||
should use the same `JtaTransactionManager` as in the previous JTA example for
|
||||
JDBC, as the following example shows:
|
||||
If you use Hibernate and Java EE container-managed JTA transactions, you should use the
|
||||
same `JtaTransactionManager` as in the previous JTA example for JDBC, as the following
|
||||
example shows:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
|
|
@ -459,7 +462,7 @@ synchronization of the resources, and exception mapping. Thus, user data access
|
|||
not have to address these tasks but can focus purely on non-boilerplate
|
||||
persistence logic. Generally, you use the native ORM API or take a template approach
|
||||
for JDBC access by using the `JdbcTemplate`. These solutions are detailed in subsequent
|
||||
chapters of this reference documentation.
|
||||
sections of this reference documentation.
|
||||
|
||||
|
||||
[[tx-resource-synchronization-low]]
|
||||
|
|
@ -576,32 +579,32 @@ on unchecked exceptions), it is often useful to customize this behavior.
|
|||
|
||||
It is not sufficient merely to tell you to annotate your classes with the
|
||||
`@Transactional` annotation, add `@EnableTransactionManagement` to your configuration,
|
||||
and expect you to understand how it all works. To provide a deeper understanding,
|
||||
this section explains the inner workings of the Spring Framework's declarative
|
||||
transaction infrastructure in the event of transaction-related issues.
|
||||
and expect you to understand how it all works. To provide a deeper understanding, this
|
||||
section explains the inner workings of the Spring Framework's declarative transaction
|
||||
infrastructure in the context of transaction-related issues.
|
||||
|
||||
The most important concepts to grasp with regard to the Spring Framework's declarative
|
||||
transaction support are that this support is enabled
|
||||
<<core.adoc#aop-understanding-aop-proxies, via AOP proxies>> and that the transactional
|
||||
advice is driven by metadata (currently XML- or annotation-based). The combination of
|
||||
AOP with transactional metadata yields an AOP proxy that uses a `TransactionInterceptor`
|
||||
in conjunction with an appropriate `TransactionManager` implementation to drive
|
||||
transactions around method invocations.
|
||||
advice is driven by metadata (currently XML- or annotation-based). The combination of AOP
|
||||
with transactional metadata yields an AOP proxy that uses a `TransactionInterceptor` in
|
||||
conjunction with an appropriate `TransactionManager` implementation to drive transactions
|
||||
around method invocations.
|
||||
|
||||
NOTE: Spring AOP is covered in <<core.adoc#aop, the AOP section>>.
|
||||
|
||||
Spring Frameworks's `TransactionInterceptor` provides transaction management for imperative
|
||||
and reactive programming models. The interceptor detects the desired flavor of transaction
|
||||
management by inspecting the method return type. Methods returning a reactive type such
|
||||
as `Publisher` or Kotlin `Flow` (or a subtype of those) qualify for reactive transaction
|
||||
management. All other return types including `void` use the code path for imperative
|
||||
transaction management.
|
||||
Spring Frameworks's `TransactionInterceptor` provides transaction management for
|
||||
imperative and reactive programming models. The interceptor detects the desired flavor of
|
||||
transaction management by inspecting the method return type. Methods returning a reactive
|
||||
type such as `Publisher` or Kotlin `Flow` (or a subtype of those) qualify for reactive
|
||||
transaction management. All other return types including `void` use the code path for
|
||||
imperative transaction management.
|
||||
|
||||
Transaction management flavors impacts which transaction manager required.
|
||||
Imperative transactions require a `PlatformTransactionManager` while reactive transactions
|
||||
use `ReactiveTransactionManager` implementations.
|
||||
Transaction management flavors impact which transaction manager is required. Imperative
|
||||
transactions require a `PlatformTransactionManager`, while reactive transactions use
|
||||
`ReactiveTransactionManager` implementations.
|
||||
|
||||
The following images shows a Conceptual view of calling a method on a transactional proxy:
|
||||
The following image shows a conceptual view of calling a method on a transactional proxy:
|
||||
|
||||
image::images/tx.png[]
|
||||
|
||||
|
|
@ -614,8 +617,9 @@ Consider the following interface and its attendant implementation. This example
|
|||
usage without focusing on a particular domain model. For the purposes of this example,
|
||||
the fact that the `DefaultFooService` class throws `UnsupportedOperationException`
|
||||
instances in the body of each implemented method is good. That behavior lets you see
|
||||
transactions be created and then rolled back in response to the
|
||||
`UnsupportedOperationException` instance. The following listing shows the `FooService` interface:
|
||||
transactions being created and then rolled back in response to the
|
||||
`UnsupportedOperationException` instance. The following listing shows the `FooService`
|
||||
interface:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -771,14 +775,14 @@ configuration is explained in detail in the next few paragraphs:
|
|||
</beans>
|
||||
----
|
||||
|
||||
Examine the preceding configuration. It assumes that you want to make a service object, the `fooService`
|
||||
bean, transactional. The transaction semantics to apply are encapsulated in the
|
||||
`<tx:advice/>` definition. The `<tx:advice/>` definition reads as "`all methods, on
|
||||
starting with `get`, are to execute in the context of a read-only transaction, and all
|
||||
other methods are to execute with the default transaction semantics`". The
|
||||
Examine the preceding configuration. It assumes that you want to make a service object,
|
||||
the `fooService` bean, transactional. The transaction semantics to apply are encapsulated
|
||||
in the `<tx:advice/>` definition. The `<tx:advice/>` definition reads as "all methods
|
||||
starting with `get` are to execute in the context of a read-only transaction, and all
|
||||
other methods are to execute with the default transaction semantics". The
|
||||
`transaction-manager` attribute of the `<tx:advice/>` tag is set to the name of the
|
||||
`TransactionManager` bean that is going to drive the transactions (in this
|
||||
case, the `txManager` bean).
|
||||
`TransactionManager` bean that is going to drive the transactions (in this case, the
|
||||
`txManager` bean).
|
||||
|
||||
TIP: You can omit the `transaction-manager` attribute in the transactional advice
|
||||
(`<tx:advice/>`) if the bean name of the `TransactionManager` that you want to
|
||||
|
|
@ -813,7 +817,7 @@ NOTE: In the preceding example, it is assumed that all your service interfaces a
|
|||
in the `x.y.service` package. See <<core.adoc#aop, the AOP section>> for more details.
|
||||
|
||||
Now that we have analyzed the configuration, you may be asking yourself,
|
||||
"`What does all this configuration actually do?`"
|
||||
"What does all this configuration actually do?"
|
||||
|
||||
The configuration shown earlier is used to create a transactional proxy around the object
|
||||
that is created from the `fooService` bean definition. The proxy is configured with
|
||||
|
|
@ -847,8 +851,8 @@ that test drives the configuration shown earlier:
|
|||
----
|
||||
|
||||
The output from running the preceding program should resemble the following (the Log4J
|
||||
output and the stack trace from the UnsupportedOperationException thrown by the
|
||||
insertFoo(..) method of the DefaultFooService class have been truncated for clarity):
|
||||
output and the stack trace from the `UnsupportedOperationException` thrown by the
|
||||
`insertFoo(..)` method of the `DefaultFooService` class have been truncated for clarity):
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
|
|
@ -882,10 +886,11 @@ insertFoo(..) method of the DefaultFooService class have been truncated for clar
|
|||
|
||||
To use reactive transaction management the code has to use reactive types.
|
||||
|
||||
NOTES: Spring Framework uses `ReactiveAdapterRegistry` to determine whether a
|
||||
method return type is reactive.
|
||||
NOTE: Spring Framework uses the `ReactiveAdapterRegistry` to determine whether a method
|
||||
return type is reactive.
|
||||
|
||||
The following listing shows the previously used `FooService` but this time the code is using reactive types:
|
||||
The following listing shows a modified version of the previously used `FooService`, but
|
||||
this time the code uses reactive types:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -921,7 +926,7 @@ The following listing shows the previously used `FooService` but this time the c
|
|||
|
||||
fun insertFoo(foo: Foo) : Mono<Void>
|
||||
|
||||
fun updateFoo(foo: Foo)
|
||||
fun updateFoo(foo: Foo) : Mono<Void>
|
||||
}
|
||||
----
|
||||
|
||||
|
|
@ -980,27 +985,27 @@ The following example shows an implementation of the preceding interface:
|
|||
}
|
||||
----
|
||||
|
||||
Imperative and reactive transaction management shares the same semantics for
|
||||
transaction boundary and transaction attribute definitions. The main difference
|
||||
to imperative transactions is the deferred nature. `TransactionInterceptor`
|
||||
decorates the returned reactive type with a transactional operator
|
||||
to begin and cleanup the transaction. Therefore, calling a transactional
|
||||
reactive method defers the actual transaction management to subscription
|
||||
type that activates processing of the reactive type.
|
||||
Imperative and reactive transaction management share the same semantics for transaction
|
||||
boundary and transaction attribute definitions. The main difference between imperative
|
||||
and reactive transactions is the deferred nature of the latter. `TransactionInterceptor`
|
||||
decorates the returned reactive type with a transactional operator to begin and clean up
|
||||
the transaction. Therefore, calling a transactional reactive method defers the actual
|
||||
transaction management to a subscription type that activates processing of the reactive
|
||||
type.
|
||||
|
||||
Another aspect of reactive transaction management relates to data escaping
|
||||
which is a natural consequence of the programming model.
|
||||
Another aspect of reactive transaction management relates to data escaping which is a
|
||||
natural consequence of the programming model.
|
||||
|
||||
Method return values of imperative transactions are returned from transactional methods
|
||||
upon successful termination of a method so that partially computed results
|
||||
do not escape the method closure.
|
||||
upon successful termination of a method so that partially computed results do not escape
|
||||
the method closure.
|
||||
|
||||
Reactive transaction methods return a reactive wrapper type which represent a
|
||||
computation sequence along with a promise to begin and complete computation.
|
||||
Reactive transaction methods return a reactive wrapper type which represents a
|
||||
computation sequence along with a promise to begin and complete the computation.
|
||||
|
||||
A `Publisher` can emit data while an transaction is ongoing but not necessarily
|
||||
completed. Therefore, methods that depend upon successful completion of an entire
|
||||
transaction need to ensure completion and buffer results in the calling code.
|
||||
A `Publisher` can emit data while a transaction is ongoing but not necessarily completed.
|
||||
Therefore, methods that depend upon successful completion of an entire transaction need
|
||||
to ensure completion and buffer results in the calling code.
|
||||
|
||||
|
||||
[[transaction-declarative-rolling-back]]
|
||||
|
|
@ -1394,14 +1399,14 @@ In XML configuration, the `<tx:annotation-driven/>` tag provides similar conveni
|
|||
<1> The line that makes the bean instance transactional.
|
||||
|
||||
|
||||
TIP: You can omit the `transaction-manager` attribute in the `<tx:annotation-driven/>` tag
|
||||
if the bean name of the `PlatformTransactionManager` that you want to wire in has the name,
|
||||
`transactionManager`. If the `TransactionManager` bean that you want to
|
||||
dependency-inject has any other name, you have to use the `transaction-manager` attribute,
|
||||
as in the preceding example.
|
||||
TIP: You can omit the `transaction-manager` attribute in the `<tx:annotation-driven/>`
|
||||
tag if the bean name of the `TransactionManager` that you want to wire in has the name,
|
||||
`transactionManager`. If the `TransactionManager` bean that you want to dependency-inject
|
||||
has any other name, you have to use the `transaction-manager` attribute, as in the
|
||||
preceding example.
|
||||
|
||||
Reactive transactional methods use reactive return types in contrast to imperative programming
|
||||
arrangements as the following listing shows:
|
||||
Reactive transactional methods use reactive return types in contrast to imperative
|
||||
programming arrangements as the following listing shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -1668,10 +1673,10 @@ Most Spring applications need only a single transaction manager, but there may b
|
|||
situations where you want multiple independent transaction managers in a single
|
||||
application. You can use the `value` or `transactionManager` attribute of the
|
||||
`@Transactional` annotation to optionally specify the identity of the
|
||||
`TransactionManager` to be used. This can either be the bean name or the
|
||||
qualifier value of the transaction manager bean. For example, using the qualifier
|
||||
notation, you can combine the following Java code with the following transaction manager
|
||||
bean declarations in the application context:
|
||||
`TransactionManager` to be used. This can either be the bean name or the qualifier value
|
||||
of the transaction manager bean. For example, using the qualifier notation, you can
|
||||
combine the following Java code with the following transaction manager bean declarations
|
||||
in the application context:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -1732,17 +1737,17 @@ The following listing shows the bean declarations:
|
|||
</bean>
|
||||
----
|
||||
|
||||
In this case, the individual methods on `TransactionalService` run under separate transaction
|
||||
managers, differentiated by the `order`, `account`, and `reactive-account` qualifiers. The default
|
||||
`<tx:annotation-driven>` target bean name, `transactionManager`, is still used if no
|
||||
specifically qualified `TransactionManager` bean is found.
|
||||
In this case, the individual methods on `TransactionalService` run under separate
|
||||
transaction managers, differentiated by the `order`, `account`, and `reactive-account`
|
||||
qualifiers. The default `<tx:annotation-driven>` target bean name, `transactionManager`,
|
||||
is still used if no specifically qualified `TransactionManager` bean is found.
|
||||
|
||||
[[tx-custom-attributes]]
|
||||
===== Custom Shortcut Annotations
|
||||
===== Custom Composed Annotations
|
||||
|
||||
If you find you repeatedly use the same attributes with `@Transactional` on many different
|
||||
methods, <<core.adoc#beans-meta-annotations, Spring's meta-annotation support>> lets you
|
||||
define custom shortcut annotations for your specific use cases. For example, consider the
|
||||
define custom composed annotations for your specific use cases. For example, consider the
|
||||
following annotation definitions:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
|
|
@ -1774,7 +1779,7 @@ following annotation definitions:
|
|||
annotation class AccountTx
|
||||
----
|
||||
|
||||
The preceding annotations lets us write the example from the previous section as follows:
|
||||
The preceding annotations let us write the example from the previous section as follows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -1809,8 +1814,9 @@ The preceding annotations lets us write the example from the previous section as
|
|||
}
|
||||
----
|
||||
|
||||
In the preceding example, we used the syntax to define the transaction manager qualifier, but we could also
|
||||
have included propagation behavior, rollback rules, timeouts, and other features.
|
||||
In the preceding example, we used the syntax to define the transaction manager qualifier,
|
||||
but we could also have included propagation behavior, rollback rules, timeouts, and other
|
||||
features.
|
||||
|
||||
|
||||
[[tx-propagation]]
|
||||
|
|
@ -2165,8 +2171,8 @@ The Spring Framework provides two means of programmatic transaction management,
|
|||
|
||||
The Spring team generally recommends the `TransactionTemplate` for programmatic
|
||||
transaction management in imperative flows and `TransactionalOperator` for reactive code.
|
||||
The second approach is similar to using the JTA
|
||||
`UserTransaction` API, although exception handling is less cumbersome.
|
||||
The second approach is similar to using the JTA `UserTransaction` API, although exception
|
||||
handling is less cumbersome.
|
||||
|
||||
|
||||
[[tx-prog-template]]
|
||||
|
|
@ -2357,18 +2363,17 @@ two distinct `TransactionTemplate` instances.
|
|||
==== Using the `TransactionOperator`
|
||||
|
||||
The `TransactionOperator` follows an operator design that is similar to other reactive
|
||||
operators. It uses a callback approach (to free application code from having to
|
||||
do the boilerplate acquisition and release transactional resources) and results in
|
||||
code that is intention driven, in that your code focuses solely on what
|
||||
you want to do.
|
||||
operators. It uses a callback approach (to free application code from having to do the
|
||||
boilerplate acquisition and release transactional resources) and results in code that is
|
||||
intention driven, in that your code focuses solely on what you want to do.
|
||||
|
||||
NOTE: As the examples that follow show, using the `TransactionOperator` absolutely
|
||||
couples you to Spring's transaction infrastructure and APIs. Whether or not programmatic
|
||||
transaction management is suitable for your development needs is a decision that you
|
||||
have to make yourself.
|
||||
transaction management is suitable for your development needs is a decision that you have
|
||||
to make yourself.
|
||||
|
||||
Application code that must execute in a transactional context and that explicitly uses the
|
||||
`TransactionOperator` resembles the next example:
|
||||
Application code that must execute in a transactional context and that explicitly uses
|
||||
the `TransactionOperator` resembles the next example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -2414,8 +2419,8 @@ Application code that must execute in a transactional context and that explicitl
|
|||
* Operator-style using Project Reactor types (`mono.as(transactionalOperator::transactional)`)
|
||||
* Callback-style for every other case (`transactionalOperator.execute(TransactionCallback<T>)`)
|
||||
|
||||
Code within the callback can roll the transaction back by calling the
|
||||
`setRollbackOnly()` method on the supplied `TransactionStatus` object, as follows:
|
||||
Code within the callback can roll the transaction back by calling the `setRollbackOnly()`
|
||||
method on the supplied `ReactiveTransaction` object, as follows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -2445,11 +2450,11 @@ Code within the callback can roll the transaction back by calling the
|
|||
===== Specifying Transaction Settings
|
||||
|
||||
You can specify transaction settings (such as the propagation mode, the isolation level,
|
||||
the timeout, and so forth) for the `TransactionalOperator`.
|
||||
By default, `TransactionalOperator` instances have the
|
||||
the timeout, and so forth) for the `TransactionalOperator`. By default,
|
||||
`TransactionalOperator` instances have
|
||||
<<transaction-declarative-txadvice-settings,default transactional settings>>. The
|
||||
following example shows customization of the transactional settings for
|
||||
a specific `TransactionalOperator:`
|
||||
following example shows customization of the transactional settings for a specific
|
||||
`TransactionalOperator:`
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -2488,16 +2493,18 @@ a specific `TransactionalOperator:`
|
|||
[[transaction-programmatic-tm]]
|
||||
==== Using the `TransactionManager`
|
||||
|
||||
The following section explains programmatic usage of imperative and reactive transaction managers.
|
||||
The following sections explain programmatic usage of imperative and reactive transaction
|
||||
managers.
|
||||
|
||||
[[transaction-programmatic-ptm]]
|
||||
===== Using the `PlatformTransactionManager`
|
||||
|
||||
For imperative transactions, you can use the `org.springframework.transaction.PlatformTransactionManager`
|
||||
directly to manage your transaction. To do so, pass the implementation of the
|
||||
`PlatformTransactionManager` you use to your bean through a bean reference. Then,
|
||||
by using the `TransactionDefinition` and `TransactionStatus` objects, you can initiate
|
||||
transactions, roll back, and commit. The following example shows how to do so:
|
||||
For imperative transactions, you can use a
|
||||
`org.springframework.transaction.PlatformTransactionManager` directly to manage your
|
||||
transaction. To do so, pass the implementation of the `PlatformTransactionManager` you
|
||||
use to your bean through a bean reference. Then, by using the `TransactionDefinition` and
|
||||
`TransactionStatus` objects, you can initiate transactions, roll back, and commit. The
|
||||
following example shows how to do so:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
@ -2540,12 +2547,12 @@ transactions, roll back, and commit. The following example shows how to do so:
|
|||
[[transaction-programmatic-rtm]]
|
||||
===== Using the `ReactiveTransactionManager`
|
||||
|
||||
When working with reactive transactions, you can use
|
||||
`org.springframework.transaction.ReactiveTransactionManager`
|
||||
directly to manage your transaction. To do so, pass the implementation of the
|
||||
`ReactiveTransactionManager` you use to your bean through a bean reference. Then,
|
||||
by using the `TransactionDefinition` and `ReactiveTransaction` objects, you can initiate
|
||||
transactions, roll back, and commit. The following example shows how to do so:
|
||||
When working with reactive transactions, you can use a
|
||||
`org.springframework.transaction.ReactiveTransactionManager` directly to manage your
|
||||
transaction. To do so, pass the implementation of the `ReactiveTransactionManager` you
|
||||
use to your bean through a bean reference. Then, by using the `TransactionDefinition` and
|
||||
`ReactiveTransaction` objects, you can initiate transactions, roll back, and commit. The
|
||||
following example shows how to do so:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
.Java
|
||||
|
|
|
|||
Loading…
Reference in New Issue