SpringBoot 开启事务的两种常用方式
前言,有时候统一异常处理不太好,因为范围太广了,很多没必要回滚的地方,因为抛了个异常都没办法继续执行别的代码,所以,可以在需要开事务的地方添加 @Transation 注解开启事务就行了。
@Configuration
@EnableTransactionManagement
public class TransactionConfig {
/**
* 配置全局事务的切点为service层的所有方法 AOP切面表达式 可参考(https://blog..net/ycf921244819/article/details/106599489)
* TODO 设置service层所在位置
*/
private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.xxx.service..*.*(..))";
private static final String[] REQUIRED_RULE_TRANSACTION = {
"insert*", "create*", "add*", "save*","modify*", "update*", "del*", "delete*"};
private static final String[] READ_RULE_TRANSACTION = {
"select*", "get*", "query*", "search*", "count*","detail*", "find*"};
/**
* 注入事务管理器
*/
@Autowired
private TransactionManager transactionManager;
/**
* 配置事务拦截器
*/
@Bean
public TransactionInterceptor txAdvice() {
RuleBasedTransactionAttribute txAttrRequired = new RuleBasedTransactionAttribute();
txAttrRequired.setName("REQUIRED事务");
//设置事务传播机制,默认是PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务
txAttrRequired.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//设置异常回滚为Exception 默认是RuntimeException
List rollbackRuleAttributes = new ArrayList<>();
rollbackRuleAttributes.add(new RollbackRuleAttribute(Exception.class));
txAttrRequired.setRollbackRules(rollbackRuleAttributes);
RuleBasedTransactionAttribute txAttrRequiredReadOnly = new RuleBasedTransactionAttribute();
txAttrRequiredReadOnly.setName("SUPPORTS事务");
//设置事务传播机制,PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行
txAttrRequiredReadOnly.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
//设置异常回滚为Exception 默认是RuntimeException
txAttrRequiredReadOnly.setRollbackRules(rollbackRuleAttributes);
txAttrRequiredReadOnly.setReadOnly(true);
/*事务管理规则,声明具备事务管理的方法名*/
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
//方法名规则限制,必须以下列开头才会加入事务管理当中
for (String s : REQUIRED_RULE_TRANSACTION) {
source.addTransactionalMethod(s, txAttrRequired);
}
//对于查询方法,根据实际情况添加事务管理 可能存在查询多个数据时,已查询出来的数据刚好被改变的情况
for (String s : READ_RULE_TRANSACTION) {
source.addTransactionalMethod(s, txAttrRequired);
}
return new TransactionInterceptor((PlatformTransactionManager) transactionManager, source);
}
/**
* 设置切面
*/
@Bean
public Advisor txAdviceAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut, txAdvice());
}
}
写在最后: 其实两种方式都不需要写 @EnableTransactionManagement 就能使用事务; 为什么SpringBoot中不需要使用@EnableTransactionManagement就能使用事务? 答:因为在SpringBoot中自动装配了此注解配置,所以已被默认启用,自然不需要手动加上此注解。 (https://blog..net/yjrguxing/article/details/113204980) (简单版:https://blog..net/m0_51512780/article/details/123241481)
