Introduce configurable default rollback rules

Includes rollbackOn annotation attribute on @EnableTransactionManagement and addDefaultRollbackRule method on AnnotationTransactionAttributeSource, as well as publicMethodsOnly as instance-level flag (also on AnnotationCacheOperationSource).

Closes gh-23473
This commit is contained in:
Juergen Hoeller
2024-03-05 18:08:08 +01:00
parent eb01cc0d9d
commit 7d4c8a403e
12 changed files with 295 additions and 71 deletions

View File

@@ -46,6 +46,7 @@ import org.springframework.transaction.testfixture.CallCountingTransactionManage
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.springframework.transaction.annotation.RollbackOn.ALL_EXCEPTIONS;
/**
* Tests demonstrating use of @EnableTransactionManagement @Configuration classes.
@@ -226,8 +227,8 @@ class EnableTransactionManagementTests {
// should throw CNFE when trying to load AnnotationTransactionAspect.
// Do you actually have org.springframework.aspects on the classpath?
assertThatException()
.isThrownBy(() -> new AnnotationConfigApplicationContext(EnableAspectjTxConfig.class, TxManagerConfig.class))
.withMessageContaining("AspectJJtaTransactionManagementConfiguration");
.isThrownBy(() -> new AnnotationConfigApplicationContext(EnableAspectjTxConfig.class, TxManagerConfig.class))
.withMessageContaining("AspectJJtaTransactionManagementConfiguration");
}
@Test
@@ -288,8 +289,8 @@ class EnableTransactionManagementTests {
}
@Test
void gh24502AppliesTransactionOnlyOnAnnotatedInterface() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Gh24502ConfigA.class);
void gh24502AppliesTransactionFromAnnotatedInterface() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Gh24502Config.class);
Object bean = ctx.getBean("testBean");
CallCountingTransactionManager txManager = ctx.getBean(CallCountingTransactionManager.class);
@@ -302,6 +303,36 @@ class EnableTransactionManagementTests {
ctx.close();
}
@Test
void gh23473AppliesToRuntimeExceptionOnly() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Gh23473ConfigA.class);
TestServiceWithRollback bean = ctx.getBean("testBean", TestServiceWithRollback.class);
CallCountingTransactionManager txManager = ctx.getBean(CallCountingTransactionManager.class);
assertThatException().isThrownBy(bean::methodOne);
assertThatException().isThrownBy(bean::methodTwo);
assertThat(txManager.begun).isEqualTo(2);
assertThat(txManager.commits).isEqualTo(2);
assertThat(txManager.rollbacks).isEqualTo(0);
ctx.close();
}
@Test
void gh23473AppliesRollbackOnAnyException() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Gh23473ConfigB.class);
TestServiceWithRollback bean = ctx.getBean("testBean", TestServiceWithRollback.class);
CallCountingTransactionManager txManager = ctx.getBean(CallCountingTransactionManager.class);
assertThatException().isThrownBy(bean::methodOne);
assertThatException().isThrownBy(bean::methodTwo);
assertThat(txManager.begun).isEqualTo(2);
assertThat(txManager.commits).isEqualTo(0);
assertThat(txManager.rollbacks).isEqualTo(2);
ctx.close();
}
@Service
public static class TransactionalTestBean {
@@ -590,7 +621,7 @@ class EnableTransactionManagementTests {
@Configuration
@EnableTransactionManagement
static class Gh24502ConfigA {
static class Gh24502Config {
@Bean
public MixedTransactionalTestService testBean() {
@@ -603,4 +634,50 @@ class EnableTransactionManagementTests {
}
}
static class TestServiceWithRollback {
@Transactional
public void methodOne() throws Exception {
throw new Exception();
}
@Transactional
public void methodTwo() throws Exception {
throw new Exception();
}
}
@Configuration
@EnableTransactionManagement
static class Gh23473ConfigA {
@Bean
public TestServiceWithRollback testBean() {
return new TestServiceWithRollback();
}
@Bean
public PlatformTransactionManager txManager() {
return new CallCountingTransactionManager();
}
}
@Configuration
@EnableTransactionManagement(rollbackOn = ALL_EXCEPTIONS)
static class Gh23473ConfigB {
@Bean
public TestServiceWithRollback testBean() {
return new TestServiceWithRollback();
}
@Bean
public PlatformTransactionManager txManager() {
return new CallCountingTransactionManager();
}
}
}