Document that @Transactional does not propagate to new threads
Closes gh-25439
This commit is contained in:
parent
b56dbd2aa8
commit
2ee231dee2
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 <<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
|
|||
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.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue