mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-05-04 05:17:15 +01:00
Accept REQUIRES_NEW on non-async transactional event listeners
See gh-30679
This commit is contained in:
+9
-7
@@ -26,6 +26,7 @@ import org.springframework.context.event.EventListener;
|
||||
import org.springframework.context.event.GenericApplicationListener;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -65,18 +66,19 @@ public class TransactionalApplicationListenerMethodAdapter extends ApplicationLi
|
||||
*/
|
||||
public TransactionalApplicationListenerMethodAdapter(String beanName, Class<?> targetClass, Method method) {
|
||||
super(beanName, targetClass, method);
|
||||
TransactionalEventListener ann =
|
||||
TransactionalEventListener eventAnn =
|
||||
AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
|
||||
if (ann == null) {
|
||||
if (eventAnn == null) {
|
||||
throw new IllegalStateException("No TransactionalEventListener annotation found on method: " + method);
|
||||
}
|
||||
if (AnnotatedElementUtils.hasAnnotation(method, Transactional.class) &&
|
||||
Transactional txAnn = AnnotatedElementUtils.findMergedAnnotation(method, Transactional.class);
|
||||
if (txAnn != null && txAnn.propagation() != Propagation.REQUIRES_NEW &&
|
||||
!AnnotatedElementUtils.hasAnnotation(method, Async.class)) {
|
||||
throw new IllegalStateException("@TransactionalEventListener method must not be annotated " +
|
||||
"with @Transactional, unless when declared as @Async: " + method);
|
||||
throw new IllegalStateException("@TransactionalEventListener method must not be annotated with " +
|
||||
"@Transactional unless when marked as REQUIRES_NEW or declared as @Async: " + method);
|
||||
}
|
||||
this.annotation = ann;
|
||||
this.transactionPhase = ann.phase();
|
||||
this.annotation = eventAnn;
|
||||
this.transactionPhase = eventAnn.phase();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+13
@@ -25,6 +25,7 @@ import org.springframework.context.event.ApplicationListenerMethodAdapter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
@@ -132,6 +133,13 @@ public class TransactionalApplicationListenerMethodAdapterTests {
|
||||
assertThatIllegalStateException().isThrownBy(() -> createTestInstance(m));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withTransactionalRequiresNewAnnotation() {
|
||||
Method m = ReflectionUtils.findMethod(SampleEvents.class, "withTransactionalRequiresNewAnnotation", String.class);
|
||||
supportsEventType(true, m, createGenericEventType(String.class));
|
||||
supportsEventType(false, m, createGenericEventType(Double.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withAsyncTransactionalAnnotation() {
|
||||
Method m = ReflectionUtils.findMethod(SampleEvents.class, "withAsyncTransactionalAnnotation", String.class);
|
||||
@@ -216,6 +224,11 @@ public class TransactionalApplicationListenerMethodAdapterTests {
|
||||
public void withTransactionalAnnotation(String data) {
|
||||
}
|
||||
|
||||
@TransactionalEventListener
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void withTransactionalRequiresNewAnnotation(String data) {
|
||||
}
|
||||
|
||||
@TransactionalEventListener
|
||||
@Async @Transactional
|
||||
public void withAsyncTransactionalAnnotation(String data) {
|
||||
|
||||
Reference in New Issue
Block a user