@@ -229,30 +229,27 @@ in the testing chapter for examples.
229
229
====
230
230
231
231
You can apply the `@Transactional` annotation to an interface definition, a method
232
- on an interface, a class definition, or a method on a class. However, the
233
- mere presence of the `@Transactional` annotation is not enough to activate the
234
- transactional behavior. The `@Transactional` annotation is merely metadata that can
235
- be consumed by some runtime infrastructure that is `@Transactional`-aware and that
236
- can use the metadata to configure the appropriate beans with transactional behavior.
237
- In the preceding example, the `<tx:annotation-driven/>` element switches on the
238
- transactional behavior.
239
-
240
- TIP: The Spring team recommends that you annotate only concrete classes (and methods of
241
- concrete classes) with the `@Transactional` annotation, as opposed to annotating interfaces.
242
- You certainly can place the `@Transactional` annotation on an interface (or an interface
243
- method), but this works only as you would expect it to if you use interface-based
244
- proxies. The fact that Java annotations are not inherited from interfaces means that,
245
- if you use class-based proxies (`proxy-target-class="true"`) or the weaving-based
246
- aspect (`mode="aspectj"`), the transaction settings are not recognized by the proxying
247
- and weaving infrastructure, and the object is not wrapped in a transactional proxy.
232
+ on an interface, a class definition, or a method on a class. However, the mere presence
233
+ of the `@Transactional` annotation is not enough to activate the transactional behavior.
234
+ The `@Transactional` annotation is merely metadata that can be consumed by corresponding
235
+ runtime infrastructure which uses that metadata to configure the appropriate beans with
236
+ transactional behavior. In the preceding example, the `<tx:annotation-driven/>` element
237
+ switches on actual transaction management at runtime.
238
+
239
+ TIP: The Spring team recommends that you annotate methods of concrete classes with the
240
+ `@Transactional` annotation, rather than relying on annotated methods in interfaces,
241
+ even if the latter does work for interface-based and target-class proxies as of 5.0.
242
+ Since Java annotations are not inherited from interfaces, interface-declared annotations
243
+ are still not recognized by the weaving infrastructure when using AspectJ mode, so the
244
+ aspect does not get applied. As a consequence, your transaction annotations may be
245
+ silently ignored: Your code might appear to "work" until you test a rollback scenario.
248
246
249
247
NOTE: In proxy mode (which is the default), only external method calls coming in through
250
248
the proxy are intercepted. This means that self-invocation (in effect, a method within
251
249
the target object calling another method of the target object) does not lead to an actual
252
250
transaction at runtime even if the invoked method is marked with `@Transactional`. Also,
253
251
the proxy must be fully initialized to provide the expected behavior, so you should not
254
- rely on this feature in your initialization code -- for example, in a `@PostConstruct`
255
- method.
252
+ rely on this feature in your initialization code -- e.g. in a `@PostConstruct` method.
256
253
257
254
Consider using AspectJ mode (see the `mode` attribute in the following table) if you
258
255
expect self-invocations to be wrapped with transactions as well. In this case, there is
@@ -277,20 +274,20 @@ is modified) to support `@Transactional` runtime behavior on any kind of method.
277
274
framework (following proxy semantics, as discussed earlier, applying to method calls
278
275
coming in through the proxy only). The alternative mode (`aspectj`) instead weaves the
279
276
affected classes with Spring's AspectJ transaction aspect, modifying the target class
280
- byte code to apply to any kind of method call. AspectJ weaving requires
281
- `spring-aspects.jar` in the classpath as well as having load-time weaving (or compile-time
282
- weaving) enabled. (See xref:core/aop/using-aspectj.adoc#aop-aj-ltw-spring[Spring configuration]
283
- for details on how to set up load-time weaving.)
277
+ byte code to apply to any kind of method call. AspectJ weaving requires `spring-aspects.jar`
278
+ in the classpath as well as having load-time weaving (or compile-time weaving) enabled.
279
+ (See xref:core/aop/using-aspectj.adoc#aop-aj-ltw-spring[Spring configuration] for details
280
+ on how to set up load-time weaving.)
284
281
285
282
| `proxy-target-class`
286
283
| `proxyTargetClass`
287
284
| `false`
288
285
| Applies to `proxy` mode only. Controls what type of transactional proxies are created
289
- for classes annotated with the `@Transactional` annotation. If the
290
- `proxy-target-class` attribute is set to `true`, class-based proxies are created.
291
- If `proxy-target-class` is ` false` or if the attribute is omitted, then standard JDK
292
- interface-based proxies are created. (See xref:core/aop/proxying.adoc[Proxying Mechanisms]
293
- for a detailed examination of the different proxy types.)
286
+ for classes annotated with the `@Transactional` annotation. If the `proxy-target-class`
287
+ attribute is set to `true`, class-based proxies are created. If `proxy-target-class` is
288
+ ` false` or if the attribute is omitted, then standard JDK interface-based proxies are
289
+ created. (See xref:core/aop/proxying.adoc[Proxying Mechanisms] for a detailed examination
290
+ of the different proxy types.)
294
291
295
292
| `order`
296
293
| `order`
0 commit comments