Explicit notes on transaction phase processing

Issue: SPR-15323
This commit is contained in:
Juergen Hoeller 2017-03-07 13:50:01 +01:00
parent 9aaed2bcef
commit 8b741508a6
3 changed files with 36 additions and 28 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@ -98,6 +98,11 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
this.phase = phase;
}
@Override
public int getOrder() {
return this.listener.getOrder();
}
@Override
public void beforeCommit(boolean readOnly) {
if (this.phase == TransactionPhase.BEFORE_COMMIT) {
@ -107,20 +112,15 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
@Override
public void afterCompletion(int status) {
if (this.phase == TransactionPhase.AFTER_COMPLETION) {
processEvent();
}
else if (this.phase == TransactionPhase.AFTER_COMMIT && status == STATUS_COMMITTED) {
if (this.phase == TransactionPhase.AFTER_COMMIT && status == STATUS_COMMITTED) {
processEvent();
}
else if (this.phase == TransactionPhase.AFTER_ROLLBACK && status == STATUS_ROLLED_BACK) {
processEvent();
}
else if (this.phase == TransactionPhase.AFTER_COMPLETION) {
processEvent();
}
@Override
public int getOrder() {
return this.listener.getOrder();
}
protected void processEvent() {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@ -22,6 +22,7 @@ import org.springframework.transaction.support.TransactionSynchronization;
* The phase at which a transactional event listener applies.
*
* @author Stephane Nicoll
* @author Juergen Hoeller
* @since 4.2
* @see TransactionalEventListener
*/
@ -33,17 +34,11 @@ public enum TransactionPhase {
*/
BEFORE_COMMIT,
/**
* Fire the event after the transaction has completed. For
* more fine-grained event, use {@link #AFTER_COMMIT} or
* {@link #AFTER_ROLLBACK} to intercept transaction commit
* or rollback respectively.
* @see TransactionSynchronization#afterCompletion(int)
*/
AFTER_COMPLETION,
/**
* 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,
* (and not in {@link TransactionSynchronization#afterCommit()}).
* @see TransactionSynchronization#afterCompletion(int)
* @see TransactionSynchronization#STATUS_COMMITTED
*/
@ -51,9 +46,20 @@ public enum TransactionPhase {
/**
* 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.
* @see TransactionSynchronization#afterCompletion(int)
* @see TransactionSynchronization#STATUS_ROLLED_BACK
*/
AFTER_ROLLBACK
AFTER_ROLLBACK,
/**
* Fire 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.
* @see TransactionSynchronization#afterCompletion(int)
*/
AFTER_COMPLETION
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@ -28,25 +28,27 @@ import org.springframework.core.annotation.AliasFor;
/**
* An {@link EventListener} that is invoked according to a {@link TransactionPhase}.
*
* <p>If the event is not published within the boundaries of a managed transaction, the event
* is discarded unless the {@link #fallbackExecution} flag is explicitly set. If a
* <p>If the event is not published within the boundaries of a managed 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}.
*
* <p>Adding {@link org.springframework.core.annotation.Order @Order} on your annotated method
* allows you to prioritize that listener amongst other listeners running in the same phase.
* <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.
*
* @author Stephane Nicoll
* @author Sam Brannen
* @since 4.2
*/
@EventListener
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EventListener
public @interface TransactionalEventListener {
/**
* Phase to bind the handling of an event to.
* <p>The default phase is {@link TransactionPhase#AFTER_COMMIT}.
* <p>If no transaction is in progress, the event is not processed at
* all unless {@link #fallbackExecution} has been enabled explicitly.
*/
@ -76,7 +78,7 @@ public @interface TransactionalEventListener {
/**
* Spring Expression Language (SpEL) attribute used for making the event
* handling conditional.
* <p>Default is {@code ""}, meaning the event is always handled.
* <p>The default is {@code ""}, meaning the event is always handled.
* @see EventListener#condition
*/
String condition() default "";