Skip to content

Commit 45cfe70

Browse files
committed
Revise transaction annotation recommendations
Closes gh-23538
1 parent 288e255 commit 45cfe70

File tree

1 file changed

+24
-27
lines changed

1 file changed

+24
-27
lines changed

src/docs/asciidoc/data-access.adoc

+24-27
Original file line numberDiff line numberDiff line change
@@ -1562,30 +1562,27 @@ chapter for examples.
15621562
====
15631563

15641564
You can apply the `@Transactional` annotation to an interface definition, a method
1565-
on an interface, a class definition, or a method on a class. However, the
1566-
mere presence of the `@Transactional` annotation is not enough to activate the
1567-
transactional behavior. The `@Transactional` annotation is merely metadata that can
1568-
be consumed by some runtime infrastructure that is `@Transactional`-aware and that
1569-
can use the metadata to configure the appropriate beans with transactional behavior.
1570-
In the preceding example, the `<tx:annotation-driven/>` element switches on the
1571-
transactional behavior.
1572-
1573-
TIP: The Spring team recommends that you annotate only concrete classes (and methods of
1574-
concrete classes) with the `@Transactional` annotation, as opposed to annotating interfaces.
1575-
You certainly can place the `@Transactional` annotation on an interface (or an interface
1576-
method), but this works only as you would expect it to if you use interface-based
1577-
proxies. The fact that Java annotations are not inherited from interfaces means that,
1578-
if you use class-based proxies (`proxy-target-class="true"`) or the weaving-based
1579-
aspect (`mode="aspectj"`), the transaction settings are not recognized by the proxying
1580-
and weaving infrastructure, and the object is not wrapped in a transactional proxy.
1565+
on an interface, a class definition, or a method on a class. However, the mere presence
1566+
of the `@Transactional` annotation is not enough to activate the transactional behavior.
1567+
The `@Transactional` annotation is merely metadata that can be consumed by corresponding
1568+
runtime infrastructure which uses that metadata to configure the appropriate beans with
1569+
transactional behavior. In the preceding example, the `<tx:annotation-driven/>` element
1570+
switches on actual transaction management at runtime.
1571+
1572+
TIP: The Spring team recommends that you annotate methods of concrete classes with the
1573+
`@Transactional` annotation, rather than relying on annotated methods in interfaces,
1574+
even if the latter does work for interface-based and target-class proxies as of 5.0.
1575+
Since Java annotations are not inherited from interfaces, interface-declared annotations
1576+
are still not recognized by the weaving infrastructure when using AspectJ mode, so the
1577+
aspect does not get applied. As a consequence, your transaction annotations may be
1578+
silently ignored: Your code might appear to "work" until you test a rollback scenario.
15811579

15821580
NOTE: In proxy mode (which is the default), only external method calls coming in through
15831581
the proxy are intercepted. This means that self-invocation (in effect, a method within
15841582
the target object calling another method of the target object) does not lead to an actual
15851583
transaction at runtime even if the invoked method is marked with `@Transactional`. Also,
15861584
the proxy must be fully initialized to provide the expected behavior, so you should not
1587-
rely on this feature in your initialization code -- for example, in a `@PostConstruct`
1588-
method.
1585+
rely on this feature in your initialization code -- e.g. in a `@PostConstruct` method.
15891586

15901587
Consider using AspectJ mode (see the `mode` attribute in the following table) if you
15911588
expect self-invocations to be wrapped with transactions as well. In this case, there is
@@ -1610,20 +1607,20 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.
16101607
framework (following proxy semantics, as discussed earlier, applying to method calls
16111608
coming in through the proxy only). The alternative mode (`aspectj`) instead weaves the
16121609
affected classes with Spring's AspectJ transaction aspect, modifying the target class
1613-
byte code to apply to any kind of method call. AspectJ weaving requires
1614-
`spring-aspects.jar` in the classpath as well as having load-time weaving (or compile-time
1615-
weaving) enabled. (See <<core.adoc#aop-aj-ltw-spring, Spring configuration>>
1616-
for details on how to set up load-time weaving.)
1610+
byte code to apply to any kind of method call. AspectJ weaving requires `spring-aspects.jar`
1611+
in the classpath as well as having load-time weaving (or compile-time weaving) enabled.
1612+
(See <<core.adoc#aop-aj-ltw-spring, Spring configuration>> for details on how to set up
1613+
load-time weaving.)
16171614

16181615
| `proxy-target-class`
16191616
| `proxyTargetClass`
16201617
| `false`
16211618
| Applies to `proxy` mode only. Controls what type of transactional proxies are created
1622-
for classes annotated with the `@Transactional` annotation. If the
1623-
`proxy-target-class` attribute is set to `true`, class-based proxies are created.
1624-
If `proxy-target-class` is `false` or if the attribute is omitted, then standard JDK
1625-
interface-based proxies are created. (See <<core.adoc#aop-proxying, Proxying Mechanisms>>
1626-
for a detailed examination of the different proxy types.)
1619+
for classes annotated with the `@Transactional` annotation. If the `proxy-target-class`
1620+
attribute is set to `true`, class-based proxies are created. If `proxy-target-class` is
1621+
`false` or if the attribute is omitted, then standard JDK interface-based proxies are
1622+
created. (See <<core.adoc#aop-proxying, Proxying Mechanisms>> for a detailed examination
1623+
of the different proxy types.)
16271624

16281625
| `order`
16291626
| `order`

0 commit comments

Comments
 (0)