I would like Spring to rollback a transaction on methods annotated with @Transactional
in case the method throws a checked exception. An equivalent of this:
@Transactional(rollbackFor=MyCheckedException.class)
public void method() throws MyCheckedException {
}
But I need this behavior to be default for all @Transactional
annotations without the need to write it everywhere. We are using Java to configure Spring (configuration classes).
I tried the configuration suggested by spring documentation , which is only available in XML. So I tried to create this XML file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" rollback-for="com.example.MyCheckedException" />
</tx:attributes>
</tx:advice>
</beans>
... and import it via @ImportResource
. Spring did recognize and parse the file (I had some errors in it at first), but it doesn't work. The behavior of @Transactional
has not changed.
I also tried defining my own transaction property source, as suggested in this answer . But it also used the XML configuration so I had to transform it into Java like this:
@Bean
public AnnotationTransactionAttributeSource getTransactionAttributeSource() {
return new RollbackForAllAnnotationTransactionAttributeSource();
}
@Bean
public TransactionInterceptor getTransactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);
return transactionInterceptor;
}
@Bean
public BeanFactoryTransactionAttributeSourceAdvisor getBeanFactoryTransactionAttributeSourceAdvisor(TransactionAttributeSource transactionAttributeSource) {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
return advisor;
}
This also didn't work - Spring kept using its own transaction property source (different instance than the one which was created in the configuration).
What is the correct way to achieve this in Java?
You should rather implement own annotation - reference
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(rollbackFor=MyCheckedException.class)
public @interface TransactionalWithRollback {
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.