Skip to content

Commit 1e1045b

Browse files
committed
Doc tx semantics for @TransactionalEventListener after completion phases
This commit improves the Javadoc regarding transactional semantics for @TransactionalEventListener methods invoked in the AFTER_COMMIT, AFTER_ROLLBACK, or AFTER_COMPLETION phase. Specifically, the documentation now points out that interactions with the underlying transactional resource will not be committed in those phases. Closes gh-26974
1 parent 8d17bce commit 1e1045b

File tree

4 files changed

+43
-19
lines changed

4 files changed

+43
-19
lines changed

spring-context/src/main/java/org/springframework/context/event/EventListener.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
* @author Sam Brannen
8585
* @since 4.2
8686
* @see EventListenerMethodProcessor
87+
* @see org.springframework.transaction.event.TransactionalEventListener
8788
*/
8889
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
8990
@Retention(RetentionPolicy.RUNTIME)

spring-tx/src/main/java/org/springframework/transaction/event/TransactionPhase.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,10 +21,11 @@
2121
import org.springframework.transaction.support.TransactionSynchronization;
2222

2323
/**
24-
* The phase at which a transactional event listener applies.
24+
* The phase in which a transactional event listener applies.
2525
*
2626
* @author Stephane Nicoll
2727
* @author Juergen Hoeller
28+
* @author Sam Brannen
2829
* @since 4.2
2930
* @see TransactionalEventListener#phase()
3031
* @see TransactionalApplicationListener#getTransactionPhase()
@@ -33,35 +34,44 @@
3334
public enum TransactionPhase {
3435

3536
/**
36-
* Fire the event before transaction commit.
37+
* Handle the event before transaction commit.
3738
* @see TransactionSynchronization#beforeCommit(boolean)
3839
*/
3940
BEFORE_COMMIT,
4041

4142
/**
42-
* Fire the event after the commit has completed successfully.
43-
* <p>Note: This is a specialization of {@link #AFTER_COMPLETION} and
44-
* therefore executes in the same after-completion sequence of events,
43+
* Handle the event after the commit has completed successfully.
44+
* <p>Note: This is a specialization of {@link #AFTER_COMPLETION} and therefore
45+
* executes in the same sequence of events as {@code AFTER_COMPLETION}
4546
* (and not in {@link TransactionSynchronization#afterCommit()}).
47+
* <p>Interactions with the underlying transactional resource will not be
48+
* committed in this phase. See
49+
* {@link TransactionSynchronization#afterCompletion(int)} for details.
4650
* @see TransactionSynchronization#afterCompletion(int)
4751
* @see TransactionSynchronization#STATUS_COMMITTED
4852
*/
4953
AFTER_COMMIT,
5054

5155
/**
52-
* Fire the event if the transaction has rolled back.
53-
* <p>Note: This is a specialization of {@link #AFTER_COMPLETION} and
54-
* therefore executes in the same after-completion sequence of events.
56+
* Handle the event if the transaction has rolled back.
57+
* <p>Note: This is a specialization of {@link #AFTER_COMPLETION} and therefore
58+
* executes in the same sequence of events as {@code AFTER_COMPLETION}.
59+
* <p>Interactions with the underlying transactional resource will not be
60+
* committed in this phase. See
61+
* {@link TransactionSynchronization#afterCompletion(int)} for details.
5562
* @see TransactionSynchronization#afterCompletion(int)
5663
* @see TransactionSynchronization#STATUS_ROLLED_BACK
5764
*/
5865
AFTER_ROLLBACK,
5966

6067
/**
61-
* Fire the event after the transaction has completed.
68+
* Handle the event after the transaction has completed.
6269
* <p>For more fine-grained events, use {@link #AFTER_COMMIT} or
6370
* {@link #AFTER_ROLLBACK} to intercept transaction commit
6471
* or rollback, respectively.
72+
* <p>Interactions with the underlying transactional resource will not be
73+
* committed in this phase. See
74+
* {@link TransactionSynchronization#afterCompletion(int)} for details.
6575
* @see TransactionSynchronization#afterCompletion(int)
6676
*/
6777
AFTER_COMPLETION

spring-tx/src/main/java/org/springframework/transaction/event/TransactionalApplicationListener.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@
3333
* transaction completion.
3434
*
3535
* <p><b>NOTE: Transactional event listeners only work with thread-bound transactions
36-
* managed by {@link org.springframework.transaction.PlatformTransactionManager}.</b>
37-
* A reactive transaction managed by {@link org.springframework.transaction.ReactiveTransactionManager}
38-
* uses the Reactor context instead of thread-local attributes, so from the perspective of
36+
* managed by a {@link org.springframework.transaction.PlatformTransactionManager
37+
* PlatformTransactionManager}.</b> A reactive transaction managed by a
38+
* {@link org.springframework.transaction.ReactiveTransactionManager ReactiveTransactionManager}
39+
* uses the Reactor context instead of thread-local variables, so from the perspective of
3940
* an event listener, there is no compatible active transaction that it can participate in.
4041
*
4142
* @author Juergen Hoeller

spring-tx/src/main/java/org/springframework/transaction/event/TransactionalEventListener.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,34 @@
2727

2828
/**
2929
* An {@link EventListener} that is invoked according to a {@link TransactionPhase}.
30-
* This is an an annotation-based equivalent of {@link TransactionalApplicationListener}.
30+
* This is an annotation-based equivalent of {@link TransactionalApplicationListener}.
3131
*
3232
* <p>If the event is not published within an active transaction, the event is discarded
3333
* unless the {@link #fallbackExecution} flag is explicitly set. If a transaction is
34-
* running, the event is processed according to its {@code TransactionPhase}.
34+
* running, the event is handled according to its {@code TransactionPhase}.
3535
*
3636
* <p>Adding {@link org.springframework.core.annotation.Order @Order} to your annotated
3737
* method allows you to prioritize that listener amongst other listeners running before
3838
* or after transaction completion.
3939
*
4040
* <p><b>NOTE: Transactional event listeners only work with thread-bound transactions
41-
* managed by {@link org.springframework.transaction.PlatformTransactionManager}.</b>
42-
* A reactive transaction managed by {@link org.springframework.transaction.ReactiveTransactionManager}
43-
* uses the Reactor context instead of thread-local attributes, so from the perspective of
41+
* managed by a {@link org.springframework.transaction.PlatformTransactionManager
42+
* PlatformTransactionManager}.</b> A reactive transaction managed by a
43+
* {@link org.springframework.transaction.ReactiveTransactionManager ReactiveTransactionManager}
44+
* uses the Reactor context instead of thread-local variables, so from the perspective of
4445
* an event listener, there is no compatible active transaction that it can participate in.
4546
*
47+
* <p><strong>WARNING:</strong> if the {@code TransactionPhase} is set to
48+
* {@link TransactionPhase#AFTER_COMMIT AFTER_COMMIT} (the default),
49+
* {@link TransactionPhase#AFTER_ROLLBACK AFTER_ROLLBACK}, or
50+
* {@link TransactionPhase#AFTER_COMPLETION AFTER_COMPLETION}, the transaction will
51+
* have been committed or rolled back already, but the transactional resources might
52+
* still be active and accessible. As a consequence, any data access code triggered
53+
* at this point will still "participate" in the original transaction, but changes
54+
* will not be committed to the transactional resource. See
55+
* {@link org.springframework.transaction.support.TransactionSynchronization#afterCompletion(int)
56+
* TransactionSynchronization.afterCompletion(int)} for details.
57+
*
4658
* @author Stephane Nicoll
4759
* @author Sam Brannen
4860
* @author Oliver Drotbohm
@@ -65,7 +77,7 @@
6577
TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;
6678

6779
/**
68-
* Whether the event should be processed if no transaction is running.
80+
* Whether the event should be handled if no transaction is running.
6981
*/
7082
boolean fallbackExecution() default false;
7183

0 commit comments

Comments
 (0)