标签:就会 Requires new his 并且 user use info 除了
首先我们的spring配置文件的配置如上图,除了指定方法外其他都是受事务控制,在某个aop切面配置路径下,如果方法有异常 则进行回滚,并且还是方法内涉及到增删改的回滚;
为了保证整体方法的事务一致性,方法内如果有多处对数据进行增删改,那么最好提取成一个service进行事务控制,如果全成功,则全部提交,否则全部回滚;
Service层test()方法:
while(条件){ // 满足条件,则对数据库增删改 }
由于公司限制,不允许贴代码
这里我在Service中进行一个wile循环,如果满足条件,我就对满足条件的这一条数据进行多次增删改;
这里有个问题,不论是否出现异常,我都catch处理了,导致了事务的大量堆积,因为while循环没跑完,test()方法没执行完,事务并不会进行提交,如果while循环中的数据量过大,很有可能造成锁库锁表的可能,会造成很多问题;
方案一:向上抽取,分割成多个独立事务
我们将test()方法中的while(条件)循环向上抽取,抽取至Controller层中,然后对满足while条件的每一条数据处理时放至一个service中,这样每次循环一次时,就整体对while中的处理提交一次事务,完美解决;
方案二:事务传播,嵌套事务,创建新的事务
带有注解@Transactional(propagation=Propagation.REQUIRES_NEW)的方法走完之后,数据就会被提交入库
while循环中如果对数据库的交互仅有一次,其他都为查询时,我建议使用这个注解,也就是说 service方法中嵌套另一个service方法,第二个service方法加上此注解,那么第二个servie方法就是新创建的事务,并进行独立提交入库;
另外需要注意方法内部调用@Transactional(propagation=Propagation.REQUIRES_NEW)注解不生效,比如A和B都在同一个方法中,A调用B,B方法是此注解,则不生效。同样,AOP拦截也拦截不到B
----REQUIRES_NEW传播说明----------------------------------------------------------------------------------------- @Service public class TestUserImpl implements TestUser { @Transactional(propagation=Propagation.REQUIRED ) public void saveUserAll(){ //1、保存用户-- this.saveUser(); //2--情况一、记录日志的方法在本service-新事务 this.saveUserLog(); //2--情况二、记录日志的方法在另一个LogService-新事务 logService.saveUserLog(); int a=1/0;//异常 } public void saveUser() { User user = new User(); userDao.save(user); } @Transactional(propagation= Propagation.REQUIRES_NEW) public void saveUserLog() { UserLog log = new UserLog(); UserLogDao.save(log); } } ------------------------------saveUserAll在位置一,出异常,执行结果------------------------------------ 情况一、记录日志的方法在本service,saveUser回滚,saveUserLog回滚 情况二、记录日志的方法在另一个LogService-新事务,saveUser回滚,saveUserLog不回滚 总结:要想总的方法的异常不影响 新事务方法REQUIRES_NEW的提交,新事务的方法,要写在另一个service里
以上是个人工作中的一些见解和想法,如有错误,欢迎指正。
标签:就会 Requires new his 并且 user use info 除了
原文地址:https://www.cnblogs.com/AlanWilliamWalker/p/11254393.html