@@ -1562,30 +1562,27 @@ chapter for examples.
1562
1562
====
1563
1563
1564
1564
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.
1581
1579
1582
1580
NOTE: In proxy mode (which is the default), only external method calls coming in through
1583
1581
the proxy are intercepted. This means that self-invocation (in effect, a method within
1584
1582
the target object calling another method of the target object) does not lead to an actual
1585
1583
transaction at runtime even if the invoked method is marked with `@Transactional`. Also,
1586
1584
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.
1589
1586
1590
1587
Consider using AspectJ mode (see the `mode` attribute in the following table) if you
1591
1588
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.
1610
1607
framework (following proxy semantics, as discussed earlier, applying to method calls
1611
1608
coming in through the proxy only). The alternative mode (`aspectj`) instead weaves the
1612
1609
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.)
1617
1614
1618
1615
| `proxy-target-class`
1619
1616
| `proxyTargetClass`
1620
1617
| `false`
1621
1618
| 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.)
1627
1624
1628
1625
| `order`
1629
1626
| `order`
0 commit comments