Browse Source

Explicit notes on class/method-level semantics in class hierarchies

Issue: SPR-17445
pull/2011/head
Juergen Hoeller 7 years ago
parent
commit
ea3250c8d6
  1. 7
      spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java
  2. 36
      src/docs/asciidoc/data-access.adoc

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

@ -27,7 +27,12 @@ import org.springframework.core.annotation.AliasFor;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
/** /**
* Describes transaction attributes on a method or class. * Describes a transaction attribute on an individual method or on a class.
*
* <p>At the class level, this annotation applies as a default to all methods of
* the declaring class and its subclasses. Note that it does not apply to ancestor
* classes up the class hierarchy; methods need to be locally redeclared in order
* to participate in a subclass-level annotation.
* *
* <p>This annotation type is generally directly comparable to Spring's * <p>This annotation type is generally directly comparable to Spring's
* {@link org.springframework.transaction.interceptor.RuleBasedTransactionAttribute} * {@link org.springframework.transaction.interceptor.RuleBasedTransactionAttribute}

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

@ -1100,8 +1100,19 @@ Consider the following class definition:
---- ----
==== ====
When the preceding POJO is defined as a bean in a Spring IoC container, you can make the bean instance Used at the class level as above, the annotation indicates a default for all methods
transactional by adding only one line of XML configuration: of the declaring class (as well as its subclasses). Alternatively, each method can
get annotated individually. Note that a class-level annotation does not apply to
ancestor classes up the class hierarchy; in such a scenario, methods need to be
locally redeclared in order to participate in a subclass-level annotation.
When a POJO class such as the one above is defined as a bean in a Spring context,
you can make the bean instance transactional through an `@EnableTransactionManagement`
annotation in a `@Configuration` class. See the
{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]
for full details.
In XML configuration, the `<tx:annotation-driven/>` tag provides similar convenience:
==== ====
[source,xml,indent=0] [source,xml,indent=0]
@ -1126,6 +1137,7 @@ transactional by adding only one line of XML configuration:
<!-- enable the configuration of transactional behavior based on annotations --> <!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/><!-- a PlatformTransactionManager is still required --> <1> <tx:annotation-driven transaction-manager="txManager"/><!-- a PlatformTransactionManager is still required --> <1>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- (this dependency is defined somewhere else) --> <!-- (this dependency is defined somewhere else) -->
<property name="dataSource" ref="dataSource"/> <property name="dataSource" ref="dataSource"/>
@ -1144,11 +1156,6 @@ if the bean name of the `PlatformTransactionManager` that you want to wire in ha
dependency-inject has any other name, you have to use the `transaction-manager` attribute, dependency-inject has any other name, you have to use the `transaction-manager` attribute,
as in the preceding example. as in the preceding example.
NOTE: If you use Java-based configuration, the `@EnableTransactionManagement` annotation
provides equivalent support . You can add the annotation to a `@Configuration` class.
See the {api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]
for full details.
.Method visibility and `@Transactional` .Method visibility and `@Transactional`
**** ****
When you use proxies, you should apply the `@Transactional` annotation only to methods When you use proxies, you should apply the `@Transactional` annotation only to methods
@ -1158,13 +1165,13 @@ method does not exhibit the configured transactional settings. If you need to an
non-public methods, consider using AspectJ (described later). non-public methods, consider using AspectJ (described later).
**** ****
You can place the `@Transactional` annotation before an interface definition, a method You can apply the `@Transactional` annotation to an interface definition, a method
on an interface, a class definition, or a public method on a class. However, the on an interface, a class definition, or a public method on a class. However, the
mere presence of the `@Transactional` annotation is not enough to activate the mere presence of the `@Transactional` annotation is not enough to activate the
transactional behavior. The `@Transactional` annotation is merely metadata that can be transactional behavior. The `@Transactional` annotation is merely metadata that can
consumed by some runtime infrastructure that is `@Transactional`-aware and that can use be consumed by some runtime infrastructure that is `@Transactional`-aware and that
the metadata to configure the appropriate beans with transactional behavior. In the can use the metadata to configure the appropriate beans with transactional behavior.
preceding example, the `<tx:annotation-driven/>` element switches on the In the preceding example, the `<tx:annotation-driven/>` element switches on the
transactional behavior. transactional behavior.
TIP: The Spring team recommends that you annotate only concrete classes (and methods of TIP: The Spring team recommends that you annotate only concrete classes (and methods of
@ -1173,9 +1180,8 @@ You certainly can place the `@Transactional` annotation on an interface (or an i
method), but this works only as you would expect it to if you use interface-based method), but this works only as you would expect it to if you use interface-based
proxies. The fact that Java annotations are not inherited from interfaces means that, proxies. The fact that Java annotations are not inherited from interfaces means that,
if you use class-based proxies (`proxy-target-class="true"`) or the weaving-based if you use class-based proxies (`proxy-target-class="true"`) or the weaving-based
aspect (`mode="aspectj"`), the transaction settings are not recognized by the aspect (`mode="aspectj"`), the transaction settings are not recognized by the proxying
proxying and weaving infrastructure, and the object is not wrapped in a and weaving infrastructure, and the object is not wrapped in a transactional proxy.
transactional proxy, which would be decidedly bad.
NOTE: In proxy mode (which is the default), only external method calls coming in through NOTE: In proxy mode (which is the default), only external method calls coming in through
the proxy are intercepted. This means that self-invocation (in effect, a method within the proxy are intercepted. This means that self-invocation (in effect, a method within

Loading…
Cancel
Save