Skip to content

Commit f789895

Browse files
committed
Correct description for class-level @transactional with AspectJ
Includes isolation level clarifications. Issue: SPR-16552 Issue: SPR-16463
1 parent bd6b7b0 commit f789895

File tree

1 file changed

+37
-38
lines changed

1 file changed

+37
-38
lines changed

src/asciidoc/data-access.adoc

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,7 @@ strategy__. A transaction strategy is defined by the
165165
----
166166
public interface PlatformTransactionManager {
167167
168-
TransactionStatus getTransaction(
169-
TransactionDefinition definition) throws TransactionException;
168+
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
170169
171170
void commit(TransactionStatus status) throws TransactionException;
172171
@@ -200,16 +199,16 @@ execution.
200199

201200
The `TransactionDefinition` interface specifies:
202201

203-
* __Isolation__: The degree to which this transaction is isolated from the work of other
204-
transactions. For example, can this transaction see uncommitted writes from other
205-
transactions?
206202
* __Propagation__: Typically, all code executed within a transaction scope will run in
207203
that transaction. However, you have the option of specifying the behavior in the event
208204
that a transactional method is executed when a transaction context already exists. For
209205
example, code can continue running in the existing transaction (the common case); or
210206
the existing transaction can be suspended and a new transaction created. __Spring
211207
offers all of the transaction propagation options familiar from EJB CMT__. To read
212208
about the semantics of transaction propagation in Spring, see <<tx-propagation>>.
209+
* __Isolation__: The degree to which this transaction is isolated from the work of other
210+
transactions. For example, can this transaction see uncommitted writes from other
211+
transactions?
213212
* __Timeout__: How long this transaction runs before timing out and being rolled back
214213
automatically by the underlying transaction infrastructure.
215214
* __Read-only status__: A read-only transaction can be used when your code reads but
@@ -837,7 +836,7 @@ unhandled `InstrumentNotFoundException`.
837836
</tx:advice>
838837
----
839838

840-
When the Spring Framework's transaction infrastructure catches an exception and is
839+
When the Spring Framework's transaction infrastructure catches an exception and it
841840
consults configured rollback rules to determine whether to mark the transaction for
842841
rollback, the __strongest__ matching rule wins. So in the case of the following
843842
configuration, any exception other than an `InstrumentNotFoundException` results in a
@@ -1028,17 +1027,17 @@ that are nested within `<tx:advice/>` and `<tx:attributes/>` tags are summarized
10281027
| `isolation`
10291028
| No
10301029
| DEFAULT
1031-
| Transaction isolation level.
1030+
| Transaction isolation level. Only applicable to propagation REQUIRED or REQUIRES_NEW.
10321031

10331032
| `timeout`
10341033
| No
10351034
| -1
1036-
| Transaction timeout value (in seconds).
1035+
| Transaction timeout (seconds). Only applicable to propagation REQUIRED or REQUIRES_NEW.
10371036

10381037
| `read-only`
10391038
| No
10401039
| false
1041-
| Is this transaction read-only?
1040+
| Read/write vs. read-only transaction. Only applicable to REQUIRED or REQUIRES_NEW.
10421041

10431042
| `rollback-for`
10441043
| No
@@ -1162,7 +1161,6 @@ transactional behavior.
11621161

11631162
[TIP]
11641163
====
1165-
11661164
Spring recommends that you only annotate concrete classes (and methods of concrete
11671165
classes) with the `@Transactional` annotation, as opposed to annotating interfaces. You
11681166
certainly can place the `@Transactional` annotation on an interface (or an interface
@@ -1308,23 +1306,23 @@ annotation are summarized in the following table:
13081306

13091307
| <<tx-multiple-tx-mgrs-with-attransactional,value>>
13101308
| String
1311-
| Optional qualifier specifying the transaction manager to be used.
1309+
| Optional qualifier specifying the transaction manager to be used.
13121310

13131311
| <<tx-propagation,propagation>>
13141312
| enum: `Propagation`
13151313
| Optional propagation setting.
13161314

13171315
| `isolation`
13181316
| enum: `Isolation`
1319-
| Optional isolation level.
1320-
1321-
| `readOnly`
1322-
| boolean
1323-
| Read/write vs. read-only transaction
1317+
| Optional isolation level. Only applicable to propagation REQUIRED or REQUIRES_NEW.
13241318

13251319
| `timeout`
13261320
| int (in seconds granularity)
1327-
| Transaction timeout.
1321+
| Optional transaction timeout. Only applicable to propagation REQUIRED or REQUIRES_NEW.
1322+
1323+
| `readOnly`
1324+
| boolean
1325+
| Read/write vs. read-only transaction. Only applicable to REQUIRED or REQUIRES_NEW.
13281326

13291327
| `rollbackFor`
13301328
| Array of `Class` objects, which must be derived from `Throwable.`
@@ -1461,8 +1459,8 @@ PROPAGATION_REQUIRED
14611459
When the propagation setting is `PROPAGATION_REQUIRED`, a __logical__ transaction scope
14621460
is created for each method upon which the setting is applied. Each such logical
14631461
transaction scope can determine rollback-only status individually, with an outer
1464-
transaction scope being logically independent from the inner transaction scope. Of
1465-
course, in case of standard `PROPAGATION_REQUIRED` behavior, all these scopes will be
1462+
transaction scope being logically independent from the inner transaction scope.
1463+
Of course, in case of standard `PROPAGATION_REQUIRED` behavior, all these scopes will be
14661464
mapped to the same physical transaction. So a rollback-only marker set in the inner
14671465
transaction scope does affect the outer transaction's chance to actually commit (as you
14681466
would expect it to).
@@ -1484,11 +1482,14 @@ image::images/tx_prop_requires_new.png[width=400]
14841482

14851483
PROPAGATION_REQUIRES_NEW
14861484

1487-
`PROPAGATION_REQUIRES_NEW`, in contrast to `PROPAGATION_REQUIRED`, uses a __completely__
1488-
independent transaction for each affected transaction scope. In that case, the
1489-
underlying physical transactions are different and hence can commit or roll back
1485+
`PROPAGATION_REQUIRES_NEW`, in contrast to `PROPAGATION_REQUIRED`, always uses an
1486+
__independent__ physical transaction for each affected transaction scope, never
1487+
participating in an existing transaction for an outer scope. In such an arrangement,
1488+
the underlying resource transactions are different and hence can commit or roll back
14901489
independently, with an outer transaction not affected by an inner transaction's rollback
1491-
status.
1490+
status, and with an inner transaction's locks released immediately after its completion.
1491+
Such an independent inner transaction may also declare its own isolation level, timeout
1492+
and read-only settings, never inheriting an outer transaction's characteristics.
14921493

14931494
[[tx-propagation-nested]]
14941495
===== Nested
@@ -1585,10 +1586,10 @@ is controlled through the `Ordered` interface. For full details on advice orderi
15851586
<!-- this is the aspect -->
15861587
<bean id="profiler" class="x.y.SimpleProfiler">
15871588
<!-- execute before the transactional advice (hence the lower order number) -->
1588-
<property name="order" __value="1"__/>
1589+
<property name="order" value="1"/>
15891590
</bean>
15901591
1591-
<tx:annotation-driven transaction-manager="txManager" __order="200"__/>
1592+
<tx:annotation-driven transaction-manager="txManager" order="200"/>
15921593
15931594
<aop:config>
15941595
<!-- this advice will execute around the transactional advice -->
@@ -1641,14 +1642,14 @@ declarative approach.
16411642
<!-- the profiling advice -->
16421643
<bean id="profiler" class="x.y.SimpleProfiler">
16431644
<!-- execute before the transactional advice (hence the lower order number) -->
1644-
__<property name="order" value="1__"/>
1645+
<property name="order" value="1"/>
16451646
</bean>
16461647
16471648
<aop:config>
16481649
<aop:pointcut id="entryPointMethod" expression="execution(* x.y..*Service.*(..))"/>
16491650
<!-- will execute after the profiling advice (c.f. the order attribute) -->
16501651
1651-
<aop:advisor advice-ref="txAdvice" pointcut-ref="entryPointMethod" __order="2__"/>
1652+
<aop:advisor advice-ref="txAdvice" pointcut-ref="entryPointMethod" order="2"/>
16521653
<!-- order value is higher than the profiling aspect -->
16531654
16541655
<aop:aspect id="profilingAspect" ref="profiler">
@@ -1721,7 +1722,7 @@ follows Java's rule that annotations on interfaces are __not inherited__.
17211722
====
17221723

17231724
The `@Transactional` annotation on a class specifies the default transaction semantics
1724-
for the execution of any method in the class.
1725+
for the execution of any public method in the class.
17251726

17261727
The `@Transactional` annotation on a method within the class overrides the default
17271728
transaction semantics given by the class annotation (if present). Any method may be
@@ -1782,7 +1783,6 @@ a transaction. You then pass an instance of your custom `TransactionCallback` to
17821783
17831784
// use constructor-injection to supply the PlatformTransactionManager
17841785
public SimpleService(PlatformTransactionManager transactionManager) {
1785-
Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
17861786
this.transactionTemplate = new TransactionTemplate(transactionManager);
17871787
}
17881788
@@ -1849,7 +1849,6 @@ a specific `TransactionTemplate:`
18491849
private final TransactionTemplate transactionTemplate;
18501850
18511851
public SimpleService(PlatformTransactionManager transactionManager) {
1852-
Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
18531852
this.transactionTemplate = new TransactionTemplate(transactionManager);
18541853
18551854
// the transaction settings can be set here explicitly if so desired
@@ -1943,9 +1942,9 @@ Registering a regular event listener is done via the `@EventListener` annotation
19431942
to bind it to the transaction use `@TransactionalEventListener`. When you do so, the listener
19441943
will be bound to the commit phase of the transaction by default.
19451944

1946-
Let's take an example to illustrate this concept. Assume that a component publish an order
1945+
Let's take an example to illustrate this concept. Assume that a component publishes an order
19471946
created event and we want to define a listener that should only handle that event once the
1948-
transaction in which it has been published as committed successfully:
1947+
transaction in which it has been published has committed successfully:
19491948

19501949
[source,java,indent=0]
19511950
[subs="verbatim,quotes"]
@@ -1960,8 +1959,8 @@ transaction in which it has been published as committed successfully:
19601959
}
19611960
----
19621961

1963-
The `TransactionalEventListener` annotation exposes a `phase` attribute that allows to customize
1964-
to which phase of the transaction the listener should be bound to. The valid phases are `BEFORE_COMMIT`,
1962+
The `TransactionalEventListener` annotation exposes a `phase` attribute that allows us to customize
1963+
which phase of the transaction the listener should be bound to. The valid phases are `BEFORE_COMMIT`,
19651964
`AFTER_COMMIT` (default), `AFTER_ROLLBACK` and `AFTER_COMPLETION` that aggregates the transaction
19661965
completion (be it a commit or a rollback).
19671966

@@ -2997,10 +2996,10 @@ An `update()` convenience method supports the retrieval of primary keys generate
29972996
database. This support is part of the JDBC 3.0 standard; see Chapter 13.6 of the
29982997
specification for details. The method takes a `PreparedStatementCreator` as its first
29992998
argument, and this is the way the required insert statement is specified. The other
3000-
argument is a `KeyHolder`, which contains the generated key on successful return from
3001-
the update. There is not a standard single way to create an appropriate
3002-
`PreparedStatement` (which explains why the method signature is the way it is). The
3003-
following example works on Oracle but may not work on other platforms:
2999+
argument is a `KeyHolder`, which contains the generated key on successful return from the
3000+
update. There is not a standard single way to create an appropriate `PreparedStatement`
3001+
(which explains why the method signature is the way it is). The following example works
3002+
on Oracle but may not work on other platforms:
30043003

30053004
[source,java,indent=0]
30063005
[subs="verbatim,quotes"]

0 commit comments

Comments
 (0)