diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java
index 4af6be76753..caad238aae1 100644
--- a/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java
+++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java
@@ -38,16 +38,25 @@ import org.springframework.transaction.TransactionDefinition;
* {@link org.springframework.transaction.interceptor.RuleBasedTransactionAttribute}
* class, and in fact {@link AnnotationTransactionAttributeSource} will directly
* convert the data to the latter class, so that Spring's transaction support code
- * does not have to know about annotations. If no rules are relevant to the exception,
- * it will be treated like
- * {@link org.springframework.transaction.interceptor.DefaultTransactionAttribute}
- * (rolling back on {@link RuntimeException} and {@link Error} but not on checked
- * exceptions).
+ * does not have to know about annotations. If no custom rollback rules apply,
+ * the transaction will roll back on {@link RuntimeException} and {@link Error}
+ * but not on checked exceptions.
*
*
For specific information about the semantics of this annotation's attributes,
* consult the {@link org.springframework.transaction.TransactionDefinition} and
* {@link org.springframework.transaction.interceptor.TransactionAttribute} javadocs.
*
+ *
This annotation commonly works with thread-bound transactions managed by
+ * {@link org.springframework.transaction.PlatformTransactionManager}, exposing a
+ * transaction to all data access operations within the current execution thread.
+ * Note: This does NOT propagate to newly started threads within the method.
+ *
+ *
Alternatively, this annotation may demarcate a reactive transaction managed
+ * by {@link org.springframework.transaction.ReactiveTransactionManager} which
+ * uses the Reactor context instead of thread-local attributes. As a consequence,
+ * all participating data access operations need to execute within the same
+ * Reactor context in the same reactive pipeline.
+ *
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @author Sam Brannen
diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/RuleBasedTransactionAttribute.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/RuleBasedTransactionAttribute.java
index ecb231abec5..0451f0518ec 100644
--- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/RuleBasedTransactionAttribute.java
+++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/RuleBasedTransactionAttribute.java
@@ -28,7 +28,7 @@ import org.springframework.lang.Nullable;
/**
* TransactionAttribute implementation that works out whether a given exception
* should cause transaction rollback by applying a number of rollback rules,
- * both positive and negative. If no rules are relevant to the exception, it
+ * both positive and negative. If no custom rollback rules apply, this attribute
* behaves like DefaultTransactionAttribute (rolling back on runtime exceptions).
*
*
{@link TransactionAttributeEditor} creates objects of this class.
diff --git a/src/docs/asciidoc/data-access.adoc b/src/docs/asciidoc/data-access.adoc
index a2ca75459c3..0fa295f6b67 100644
--- a/src/docs/asciidoc/data-access.adoc
+++ b/src/docs/asciidoc/data-access.adoc
@@ -566,7 +566,7 @@ abstractions mentioned earlier.
[[transaction-declarative]]
-=== Declarative transaction management
+=== Declarative Transaction Management
NOTE: Most Spring Framework users choose declarative transaction management. This option has
the least impact on application code and, hence, is most consistent with the ideals of a
@@ -637,7 +637,7 @@ around method invocations.
NOTE: Spring AOP is covered in <>.
-Spring Frameworks's `TransactionInterceptor` provides transaction management for
+Spring Framework'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
@@ -648,6 +648,18 @@ Transaction management flavors impact which transaction manager is required. Imp
transactions require a `PlatformTransactionManager`, while reactive transactions use
`ReactiveTransactionManager` implementations.
+[NOTE]
+====
+`@Transactional` commonly works with thread-bound transactions managed by
+`PlatformTransactionManager`, exposing a transaction to all data access operations within
+the current execution thread. Note: This does _not_ propagate to newly started threads
+within the method.
+
+A reactive transaction managed by `ReactiveTransactionManager` uses the Reactor context
+instead of thread-local attributes. As a consequence, all participating data access
+operations need to execute within the same Reactor context in the same reactive pipeline.
+====
+
The following image shows a conceptual view of calling a method on a transactional proxy:
image::images/tx.png[]
@@ -2844,30 +2856,29 @@ specific to each technology.
Spring provides a convenient translation from technology-specific exceptions, such as
`SQLException` to its own exception class hierarchy, which has `DataAccessException` as
-the root exception. These exceptions wrap the original exception so that there is never any
-risk that you might lose any information about what might have gone wrong.
+the root exception. These exceptions wrap the original exception so that there is never
+any risk that you might lose any information about what might have gone wrong.
In addition to JDBC exceptions, Spring can also wrap JPA- and Hibernate-specific exceptions,
-converting them to a set of focused runtime exceptions.
-This lets you handle most non-recoverable persistence exceptions
-in only the appropriate layers, without having annoying boilerplate
-catch-and-throw blocks and exception declarations in your DAOs. (You can still trap
-and handle exceptions anywhere you need to though.) As mentioned above, JDBC
-exceptions (including database-specific dialects) are also converted to the same
+converting them to a set of focused runtime exceptions. This lets you handle most
+non-recoverable persistence exceptions in only the appropriate layers, without having
+annoying boilerplate catch-and-throw blocks and exception declarations in your DAOs.
+(You can still trap and handle exceptions anywhere you need to though.) As mentioned above,
+JDBC exceptions (including database-specific dialects) are also converted to the same
hierarchy, meaning that you can perform some operations with JDBC within a consistent
programming model.
-The preceding discussion holds true for the various template classes in Spring's support for various ORM
-frameworks. If you use the interceptor-based classes, the application must care
-about handling `HibernateExceptions` and `PersistenceExceptions` itself, preferably by
-delegating to the `convertHibernateAccessException(..)` or
-`convertJpaAccessException()` methods, respectively, of `SessionFactoryUtils`. These methods convert the exceptions
+The preceding discussion holds true for the various template classes in Spring's support
+for various ORM frameworks. If you use the interceptor-based classes, the application must
+care about handling `HibernateExceptions` and `PersistenceExceptions` itself, preferably by
+delegating to the `convertHibernateAccessException(..)` or `convertJpaAccessException(..)`
+methods, respectively, of `SessionFactoryUtils`. These methods convert the exceptions
to exceptions that are compatible with the exceptions in the `org.springframework.dao`
-exception hierarchy. As `PersistenceExceptions` are unchecked, they can get
-thrown, too (sacrificing generic DAO abstraction in terms of exceptions, though).
+exception hierarchy. As `PersistenceExceptions` are unchecked, they can get thrown, too
+(sacrificing generic DAO abstraction in terms of exceptions, though).
-The following image shows the exception hierarchy that Spring provides. (Note that the
-class hierarchy detailed in the image shows only a subset of the entire
+The following image shows the exception hierarchy that Spring provides.
+(Note that the class hierarchy detailed in the image shows only a subset of the entire
`DataAccessException` hierarchy.)
image::images/DataAccessException.png[]
@@ -4232,14 +4243,14 @@ interface that wraps a single `Connection` that is not closed after each use.
This is not multi-threading capable.
If any client code calls `close` on the assumption of a pooled connection (as when using
-persistence tools), you should set the `suppressClose` property to `true`. This setting returns a
-close-suppressing proxy that wraps the physical connection. Note that you can no longer
-cast this to a native Oracle `Connection` or a similar object.
+persistence tools), you should set the `suppressClose` property to `true`. This setting
+returns a close-suppressing proxy that wraps the physical connection. Note that you can
+no longer cast this to a native Oracle `Connection` or a similar object.
-`SingleConnectionDataSource` is primarily a test class. For example, it enables easy testing of code outside an
-application server, in conjunction with a simple JNDI environment. In contrast to
-`DriverManagerDataSource`, it reuses the same connection all the time, avoiding
-excessive creation of physical connections.
+`SingleConnectionDataSource` is primarily a test class. It typically enables easy testing
+of code outside an application server, in conjunction with a simple JNDI environment.
+In contrast to `DriverManagerDataSource`, it reuses the same connection all the time,
+avoiding excessive creation of physical connections.
@@ -8810,8 +8821,8 @@ can do so by using the following `applicationContext.xml`:
----
This application context uses XStream, but we could have used any of the other marshaller
-instances described later in this chapter. Note that, by default, XStream does not require any further
-configuration, so the bean definition is rather simple. Also note that the
+instances described later in this chapter. Note that, by default, XStream does not require
+any further configuration, so the bean definition is rather simple. Also note that the
`XStreamMarshaller` implements both `Marshaller` and `Unmarshaller`, so we can refer to the
`xstreamMarshaller` bean in both the `marshaller` and `unmarshaller` property of the
application.
@@ -8829,8 +8840,8 @@ This sample application produces the following `settings.xml` file:
[[oxm-schema-based-config]]
=== XML Configuration Namespace
-You can configure marshallers more concisely by using tags from the OXM namespace. To
-make these tags available, you must first reference the appropriate schema in the
+You can configure marshallers more concisely by using tags from the OXM namespace.
+To make these tags available, you must first reference the appropriate schema in the
preamble of the XML configuration file. The following example shows how to do so:
[source,xml,indent=0]
@@ -9073,7 +9084,7 @@ vulnerabilities do not get invoked.
NOTE: Note that XStream is an XML serialization library, not a data binding library.
Therefore, it has limited namespace support. As a result, it is rather unsuitable for usage
-within Web services.
+within Web Services.