Skip to content

Commit ea3250c

Browse files
committed
Explicit notes on class/method-level semantics in class hierarchies
Issue: SPR-17445
1 parent b1f5f51 commit ea3250c

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@
2727
import org.springframework.transaction.TransactionDefinition;
2828

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

src/docs/asciidoc/data-access.adoc

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,8 +1100,19 @@ Consider the following class definition:
11001100
----
11011101
====
11021102

1103-
When the preceding POJO is defined as a bean in a Spring IoC container, you can make the bean instance
1104-
transactional by adding only one line of XML configuration:
1103+
Used at the class level as above, the annotation indicates a default for all methods
1104+
of the declaring class (as well as its subclasses). Alternatively, each method can
1105+
get annotated individually. Note that a class-level annotation does not apply to
1106+
ancestor classes up the class hierarchy; in such a scenario, methods need to be
1107+
locally redeclared in order to participate in a subclass-level annotation.
1108+
1109+
When a POJO class such as the one above is defined as a bean in a Spring context,
1110+
you can make the bean instance transactional through an `@EnableTransactionManagement`
1111+
annotation in a `@Configuration` class. See the
1112+
{api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]
1113+
for full details.
1114+
1115+
In XML configuration, the `<tx:annotation-driven/>` tag provides similar convenience:
11051116

11061117
====
11071118
[source,xml,indent=0]
@@ -1126,6 +1137,7 @@ transactional by adding only one line of XML configuration:
11261137
11271138
<!-- enable the configuration of transactional behavior based on annotations -->
11281139
<tx:annotation-driven transaction-manager="txManager"/><!-- a PlatformTransactionManager is still required --> <1>
1140+
11291141
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
11301142
<!-- (this dependency is defined somewhere else) -->
11311143
<property name="dataSource" ref="dataSource"/>
@@ -1144,11 +1156,6 @@ if the bean name of the `PlatformTransactionManager` that you want to wire in ha
11441156
dependency-inject has any other name, you have to use the `transaction-manager` attribute,
11451157
as in the preceding example.
11461158

1147-
NOTE: If you use Java-based configuration, the `@EnableTransactionManagement` annotation
1148-
provides equivalent support . You can add the annotation to a `@Configuration` class.
1149-
See the {api-spring-framework}/transaction/annotation/EnableTransactionManagement.html[javadoc]
1150-
for full details.
1151-
11521159
.Method visibility and `@Transactional`
11531160
****
11541161
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
11581165
non-public methods, consider using AspectJ (described later).
11591166
****
11601167

1161-
You can place the `@Transactional` annotation before an interface definition, a method
1168+
You can apply the `@Transactional` annotation to an interface definition, a method
11621169
on an interface, a class definition, or a public method on a class. However, the
11631170
mere presence of the `@Transactional` annotation is not enough to activate the
1164-
transactional behavior. The `@Transactional` annotation is merely metadata that can be
1165-
consumed by some runtime infrastructure that is `@Transactional`-aware and that can use
1166-
the metadata to configure the appropriate beans with transactional behavior. In the
1167-
preceding example, the `<tx:annotation-driven/>` element switches on the
1171+
transactional behavior. The `@Transactional` annotation is merely metadata that can
1172+
be consumed by some runtime infrastructure that is `@Transactional`-aware and that
1173+
can use the metadata to configure the appropriate beans with transactional behavior.
1174+
In the preceding example, the `<tx:annotation-driven/>` element switches on the
11681175
transactional behavior.
11691176

11701177
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
11731180
method), but this works only as you would expect it to if you use interface-based
11741181
proxies. The fact that Java annotations are not inherited from interfaces means that,
11751182
if you use class-based proxies (`proxy-target-class="true"`) or the weaving-based
1176-
aspect (`mode="aspectj"`), the transaction settings are not recognized by the
1177-
proxying and weaving infrastructure, and the object is not wrapped in a
1178-
transactional proxy, which would be decidedly bad.
1183+
aspect (`mode="aspectj"`), the transaction settings are not recognized by the proxying
1184+
and weaving infrastructure, and the object is not wrapped in a transactional proxy.
11791185

11801186
NOTE: In proxy mode (which is the default), only external method calls coming in through
11811187
the proxy are intercepted. This means that self-invocation (in effect, a method within

0 commit comments

Comments
 (0)