Browse Source

Document that @Transactional does not propagate to new threads

Closes gh-25439
pull/26108/head
Juergen Hoeller 4 years ago
parent
commit
2ee231dee2
  1. 19
      spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java
  2. 2
      spring-tx/src/main/java/org/springframework/transaction/interceptor/RuleBasedTransactionAttribute.java
  3. 73
      src/docs/asciidoc/data-access.adoc

19
spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java

@ -38,16 +38,25 @@ import org.springframework.transaction.TransactionDefinition; @@ -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.
*
* <p>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.
*
* <p>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.
* <b>Note: This does NOT propagate to newly started threads within the method.</b>
*
* <p>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

2
spring-tx/src/main/java/org/springframework/transaction/interceptor/RuleBasedTransactionAttribute.java

@ -28,7 +28,7 @@ import org.springframework.lang.Nullable; @@ -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).
*
* <p>{@link TransactionAttributeEditor} creates objects of this class.

73
src/docs/asciidoc/data-access.adoc

@ -566,7 +566,7 @@ abstractions mentioned earlier. @@ -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. @@ -637,7 +637,7 @@ around method invocations.
NOTE: Spring AOP is covered in <<core.adoc#aop, the AOP section>>.
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 @@ -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. @@ -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. @@ -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`: @@ -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: @@ -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. @@ -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.

Loading…
Cancel
Save