diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java index 373035d90dc..7e050ef212e 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java @@ -360,7 +360,7 @@ public class SimpleAsyncTaskScheduler extends SimpleAsyncTaskExecutor implements @Override public boolean isRunning() { - return this.triggerLifecycle.isRunning(); + return (this.triggerLifecycle.isRunning() || this.fixedDelayLifecycle.isRunning()); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java index b72e1331d84..39663c32ea2 100644 --- a/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java +++ b/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java @@ -342,7 +342,6 @@ public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator this.active = false; Set threads = this.activeThreads; if (threads != null) { - threads.forEach(Thread::interrupt); synchronized (threads) { try { if (!threads.isEmpty()) { @@ -353,6 +352,7 @@ public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator Thread.currentThread().interrupt(); } } + threads.forEach(Thread::interrupt); } } } diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/RestrictedTransactionalEventListenerFactory.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/RestrictedTransactionalEventListenerFactory.java index d480170357f..bcf36846254 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/RestrictedTransactionalEventListenerFactory.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/RestrictedTransactionalEventListenerFactory.java @@ -20,6 +20,8 @@ import java.lang.reflect.Method; import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.transaction.event.TransactionPhase; +import org.springframework.transaction.event.TransactionalApplicationListenerMethodAdapter; import org.springframework.transaction.event.TransactionalEventListenerFactory; /** @@ -37,20 +39,22 @@ public class RestrictedTransactionalEventListenerFactory extends TransactionalEv @Override public ApplicationListener createApplicationListener(String beanName, Class type, Method method) { - Transactional txAnn = AnnotatedElementUtils.findMergedAnnotation(method, Transactional.class); - - if (txAnn == null) { - txAnn = AnnotatedElementUtils.findMergedAnnotation(type, Transactional.class); - } - - if (txAnn != null) { - Propagation propagation = txAnn.propagation(); - if (propagation != Propagation.REQUIRES_NEW && propagation != Propagation.NOT_SUPPORTED) { - throw new IllegalStateException("@TransactionalEventListener method must not be annotated with " + - "@Transactional unless when declared as REQUIRES_NEW or NOT_SUPPORTED: " + method); + TransactionalApplicationListenerMethodAdapter adapter = + new TransactionalApplicationListenerMethodAdapter(beanName, type, method); + if (adapter.getTransactionPhase() != TransactionPhase.BEFORE_COMMIT) { + Transactional txAnn = AnnotatedElementUtils.findMergedAnnotation(method, Transactional.class); + if (txAnn == null) { + txAnn = AnnotatedElementUtils.findMergedAnnotation(type, Transactional.class); + } + if (txAnn != null) { + Propagation propagation = txAnn.propagation(); + if (propagation != Propagation.REQUIRES_NEW && propagation != Propagation.NOT_SUPPORTED) { + throw new IllegalStateException("@TransactionalEventListener method must not be annotated with " + + "@Transactional unless when declared as REQUIRES_NEW or NOT_SUPPORTED: " + method); + } } } - return super.createApplicationListener(beanName, type, method); + return adapter; } } diff --git a/spring-tx/src/test/java/org/springframework/transaction/event/TransactionalApplicationListenerMethodAdapterTests.java b/spring-tx/src/test/java/org/springframework/transaction/event/TransactionalApplicationListenerMethodAdapterTests.java index 54283661ccf..aa32b9f37a7 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/event/TransactionalApplicationListenerMethodAdapterTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/event/TransactionalApplicationListenerMethodAdapterTests.java @@ -157,6 +157,13 @@ class TransactionalApplicationListenerMethodAdapterTests { assertThatNoException().isThrownBy(() -> factory.createApplicationListener("test", SampleEvents.class, m)); } + @Test + void withTransactionalAnnotationBeforeCommit() { + RestrictedTransactionalEventListenerFactory factory = new RestrictedTransactionalEventListenerFactory(); + Method m = ReflectionUtils.findMethod(SampleEvents.class, "withTransactionalAnnotationBeforeCommit", String.class); + assertThatNoException().isThrownBy(() -> factory.createApplicationListener("test", SampleEvents.class, m)); + } + @Test void withTransactionalAnnotationOnEnclosingClass() { RestrictedTransactionalEventListenerFactory factory = new RestrictedTransactionalEventListenerFactory(); @@ -277,6 +284,11 @@ class TransactionalApplicationListenerMethodAdapterTests { public void withAsyncTransactionalAnnotation(String data) { } + @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT) + @Transactional + public void withTransactionalAnnotationBeforeCommit(String data) { + } + @Transactional static class SampleEventsWithTransactionalAnnotation {