springboot 配置全局 事务

导入aop
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

可以复制用

package org.mallOnline.admin.config;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;

@Aspect
@Configuration
public class TransactionAdviceConfig {
																	//*后面要有空格
	private static final String AOP_POINTCUT_EXPRESSION = "execution (* org.mallOnline.admin.service.*.*(..))";

	@Autowired
	private PlatformTransactionManager transactionManager;
	
	@Bean
	public TransactionInterceptor txAdvice(){
		DefaultTransactionAttribute tAttr_REQUIRED=new DefaultTransactionAttribute();
		tAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		
		DefaultTransactionAttribute tAttr_REQUIRED_READONLY=new DefaultTransactionAttribute();
		tAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		tAttr_REQUIRED_READONLY.setReadOnly(true);
		
		NameMatchTransactionAttributeSource source=new NameMatchTransactionAttributeSource();
		source.addTransactionalMethod("add*", tAttr_REQUIRED);
        source.addTransactionalMethod("save*", tAttr_REQUIRED);
        source.addTransactionalMethod("delete*", tAttr_REQUIRED);
        source.addTransactionalMethod("update*", tAttr_REQUIRED);
        source.addTransactionalMethod("exec*", tAttr_REQUIRED);
        source.addTransactionalMethod("set*", tAttr_REQUIRED);
        source.addTransactionalMethod("get*", tAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("query*", tAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("find*", tAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("list*", tAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("count*", tAttr_REQUIRED_READONLY);
        source.addTransactionalMethod("is*", tAttr_REQUIRED_READONLY);
        return new TransactionInterceptor(transactionManager, source);
	}
	
	@Bean
	public Advisor txAdviceAdvisor(){
		AspectJExpressionPointcut pointcut=new AspectJExpressionPointcut();
		pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
		return new DefaultPointcutAdvisor(pointcut, txAdvice());
	}
	
}

try{}catch{}中事务不回滚

回滚只有在RunTimeException 或者 Error时,才会发生回滚。而常见的非RunTimeException是不会触发事务回滚的。

RunTimeException:这样的异常在程序里不做处理,不会报错,运行时才会报错,例如:NullPointerException空指针异常。
非RunTimeException:在程序里要进行try catch处理,不进行处理就会报错

处理事务不回滚的几种方法:

1.抛出@Transactional注解默认识别的RuntimeException
public int saveBatch(){
	Logger logger=LogManager.getLogger();
	try {
		List<UmsRole> ls=new ArrayList<UmsRole>();
		ls.add(new UmsRole("zhangsan1"));
		ls.add(new UmsRole());
		ls.add(new UmsRole("zhangsan"));
		for (UmsRole umsRole : ls) {
			roleMapper.insertSelective(umsRole);
		}
		
	} catch (Exception e) {
		logger.error(e);
		throw new RuntimeException();
	}
	
	return 1;
}
2. 使用@Transactional(rollbackFor = { Exception.class }),抛出捕获的非RuntimeException异常

方法上使用@Transactional(rollbackFor = { Exception.class })注解声明事务回滚级别,在捕获到异常时在catch语句中直接抛出所捕获的异常。

@Transactional(rollbackFor={Exception.class})
public int saveBatch(){
	Logger logger=LogManager.getLogger();
	try {
		List<UmsRole> ls=new ArrayList<UmsRole>();
		ls.add(new UmsRole("zhangsan1"));
		ls.add(new UmsRole());
		ls.add(new UmsRole("zhangsan"));
		for (UmsRole umsRole : ls) {
			roleMapper.insertSelective(umsRole);
		}
		
	} catch (Exception e) {
		logger.error(e);
		throw e;
	}
	
	return 1;
}
3. 手动回滚

上面两个在catch{…}中抛出异常的方法都有个不足之处,就是不能在catch{…}中存在return子句,所以设置手动回滚,当捕获到异常时,手动回滚,同时返回前台提示信息

public int saveBatch(){
	Logger logger=LogManager.getLogger();
	try {
		List<UmsRole> ls=new ArrayList<UmsRole>();
		ls.add(new UmsRole("zhangsan1"));
		ls.add(new UmsRole());
		ls.add(new UmsRole("zhangsan"));
		for (UmsRole umsRole : ls) {
			roleMapper.insertSelective(umsRole);
		}
		
	} catch (Exception e) {
		logger.error(e);
		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
	}
	
	return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值