Skip to content

Commit

Permalink
Doc tx semantics for @TransactionalEventListener after completion phases
Browse files Browse the repository at this point in the history
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 spring-projectsgh-26974
  • Loading branch information
sbrannen committed May 26, 2021
1 parent 9018356 commit 911aca1
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
* @author Sam Brannen
* @since 4.2
* @see EventListenerMethodProcessor
* @see org.springframework.transaction.event.TransactionalEventListener
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,45 +19,55 @@
import org.springframework.transaction.support.TransactionSynchronization;

/**
* The phase at which a transactional event listener applies.
* The phase in which a transactional event listener applies.
*
* @author Stephane Nicoll
* @author Juergen Hoeller
* @author Sam Brannen
* @since 4.2
* @see TransactionalEventListener
*/
public enum TransactionPhase {

/**
* Fire the event before transaction commit.
* Handle the event before transaction commit.
* @see TransactionSynchronization#beforeCommit(boolean)
*/
BEFORE_COMMIT,

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

/**
* Fire the event if the transaction has rolled back.
* <p>Note: This is a specialization of {@link #AFTER_COMPLETION} and
* therefore executes in the same after-completion sequence of events.
* Handle the event if the transaction has rolled back.
* <p>Note: This is a specialization of {@link #AFTER_COMPLETION} and therefore
* executes in the same sequence of events as {@code AFTER_COMPLETION}.
* <p>Interactions with the underlying transactional resource will not be
* committed in this phase. See
* {@link TransactionSynchronization#afterCompletion(int)} for details.
* @see TransactionSynchronization#afterCompletion(int)
* @see TransactionSynchronization#STATUS_ROLLED_BACK
*/
AFTER_ROLLBACK,

/**
* Fire the event after the transaction has completed.
* Handle the event after the transaction has completed.
* <p>For more fine-grained events, use {@link #AFTER_COMMIT} or
* {@link #AFTER_ROLLBACK} to intercept transaction commit
* or rollback, respectively.
* <p>Interactions with the underlying transactional resource will not be
* committed in this phase. See
* {@link TransactionSynchronization#afterCompletion(int)} for details.
* @see TransactionSynchronization#afterCompletion(int)
*/
AFTER_COMPLETION
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -30,18 +30,30 @@
*
* <p>If the event is not published within an active transaction, the event is discarded
* unless the {@link #fallbackExecution} flag is explicitly set. If a transaction is
* running, the event is processed according to its {@code TransactionPhase}.
* running, the event is handled according to its {@code TransactionPhase}.
*
* <p>Adding {@link org.springframework.core.annotation.Order @Order} to your annotated
* method allows you to prioritize that listener amongst other listeners running before
* or after transaction completion.
*
* <p><b>NOTE: Transactional event listeners only work with thread-bound transactions
* managed by {@link org.springframework.transaction.PlatformTransactionManager}.</b>
* A reactive transaction managed by {@link org.springframework.transaction.ReactiveTransactionManager}
* uses the Reactor context instead of thread-local attributes, so from the perspective of
* managed by a {@link org.springframework.transaction.PlatformTransactionManager
* PlatformTransactionManager}.</b> A reactive transaction managed by a
* {@link org.springframework.transaction.ReactiveTransactionManager ReactiveTransactionManager}
* uses the Reactor context instead of thread-local variables, so from the perspective of
* an event listener, there is no compatible active transaction that it can participate in.
*
* <p><strong>WARNING:</strong> if the {@code TransactionPhase} is set to
* {@link TransactionPhase#AFTER_COMMIT AFTER_COMMIT} (the default),
* {@link TransactionPhase#AFTER_ROLLBACK AFTER_ROLLBACK}, or
* {@link TransactionPhase#AFTER_COMPLETION AFTER_COMPLETION}, the transaction will
* have been committed or rolled back already, but the transactional resources might
* still be active and accessible. As a consequence, any data access code triggered
* at this point will still "participate" in the original transaction, but changes
* will not be committed to the transactional resource. See
* {@link org.springframework.transaction.support.TransactionSynchronization#afterCompletion(int)
* TransactionSynchronization.afterCompletion(int)} for details.
*
* @author Stephane Nicoll
* @author Sam Brannen
* @since 4.2
Expand All @@ -61,7 +73,7 @@
TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;

/**
* Whether the event should be processed if no transaction is running.
* Whether the event should be handled if no transaction is running.
*/
boolean fallbackExecution() default false;

Expand Down

0 comments on commit 911aca1

Please sign in to comment.