Spring注解式事务失效问题记录
程序员文章站
2022-05-31 11:46:28
...
Spring注解式事务失效问题记录
进入甲方弘康人寿后,搭建保全中心时,遇到的一个问题,同一个类中的一个事务方法调用另一个事务时,第二个事务会失效的问题
本文此次仅仅做个记录,这段时间忙完之后再好好梳理下事务这块。spring事物是基于类和接口的所以只能在类里面调用另一个类里面的事物,同一个类里面调用自己类的事物方法是无效的。
* spring事物也不要频繁使用,在事物处理的同时操作的第一张表会被限制查看的(即被临时锁住)。数据量大的时候会有一定影响。 * 解决方法 * 1.在新增类中调用事务 * 2.用AopContext代理调用 ps: ((TestTransactional)AopContext.currentProxy()).add1(); */
本类中的一个事务方法调用第二个事务方法时,第二个事务会失效
package com.huida.investment.controller; import com.huida.investment.entity.LdcodeEntity; import com.huida.investment.service.base.LdcodeService; import org.apache.catalina.core.ApplicationContext; import org.springframework.aop.framework.AopContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * @description: 事务demo * 1.propagation-required: 支持当前事务,如果有就加入当前事务中;如果当前方法没有事务,就新建一个事务; 2.propagation-supports: 支持当前事务,如果有就加入当前事务中;如果当前方法没有事务,就以非事务的方式执行; 3.propagation-mandatory: 支持当前事务,如果有就加入当前事务中;如果当前没有事务,就抛出异常; 4.propagation-requires_new: 新建事务,如果当前存在事务,就把当前事务挂起;如果当前方法没有事务,就新建事务; 5.propagation-not-supported: 以非事务方式执行,如果当前方法存在事务就挂起当前事务;如果当前方法不存在事务,就以非事务方式执行; 6.propagation-never: 以非事务方式执行,如果当前方法存在事务就抛出异常;如果当前方法不存在事务,就以非事务方式执行; 7.propagation-nested: 如果当前方法有事务,则在嵌套事务内执行;如果当前方法没有事务,则与required操作类似; * @author: zhanghailang * @date: 2020-10-14 14:54 */ @RestController public class TestTransactional { @Autowired LdcodeService ldcodeService; @Autowired TestTransational2 testTransational2; @GetMapping(value = "/get1") @Transactional(rollbackFor = Exception.class) public String add() throws InterruptedException { LdcodeEntity ldcodeEntity = new LdcodeEntity(); ldcodeEntity.setCodename("事务demo"); ldcodeEntity.setCodetype("TestTrans9"); ldcodeEntity.setCode("test129"); ldcodeService.save(ldcodeEntity); List<String> list = ldcodeService.queryTLRiskCode(); // //本类中新的事务 //catch 住新事务的异常 // try { // add1(); // }catch (Exception e){ // System.out.println("第二个事务的异常被catch"); // } // Thread.sleep(20000); // System.out.println("事务结束"); //使用代理的方式获取本类中第二个事务方法 ((TestTransactional)AopContext.currentProxy()).add1(); //从另一个类中调用第二个事物的方法 // testTransational2.add1(); throw new RuntimeException("1111"); // return list.get(1); } /** * spring事物是基于类和接口的所以只能在类里面调用另一个类里面的事物,同一个类里面调用自己类的事物方法是无效的。 * spring事物也不要频繁使用,在事物处理的同时操作的第一张表会被限制查看的(即被临时锁住)。数据量大的时候会有一定影响。 * 解决方法 * 1.在新增类中调用事务 * 2.用AopContext代理调用 ps: ((TestTransactional)AopContext.currentProxy()).add1(); */ @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class) public void add1() { //本类中的第二个事务不会生效,无论事务隔离级别是哪种 原因是aop的动态代理 //TODO //如果希望第二个事务可以提前提交,第一个事务回滚时还可以将第二个事务回滚 ????? System.out.println("本类中的第二个事务"); LdcodeEntity ldcodeEntity = new LdcodeEntity(); ldcodeEntity.setCodename("事务demo"); ldcodeEntity.setCodetype("NewTestTrans9"); ldcodeEntity.setCode("ntest139"); ldcodeService.save(ldcodeEntity); // throw new RuntimeException("1111"); System.out.println("第二个事务#############"); } }
将第二个事务方法添加到新增类中,事务才会生效
package com.huida.investment.controller; import com.huida.investment.entity.LdcodeEntity; import com.huida.investment.service.base.LdcodeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @description: 第二个事务服务类 * @author: zhanghailang * @date: 2020-10-14 16:07 */ @Component public class TestTransational2 { @Autowired LdcodeService ldcodeService ; @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class) public void add1() { System.out.println("这是另一个类中的第二个事务"); LdcodeEntity ldcodeEntity = new LdcodeEntity(); ldcodeEntity.setCodename("事务demo"); ldcodeEntity.setCodetype("NewTestTrans8"); ldcodeEntity.setCode("ntest138"); ldcodeService.save(ldcodeEntity); // throw new RuntimeException("1111"); System.out.println("第二个事务#############"); } }
下一篇: mysql索引失效问题记录
推荐阅读
-
Spring事务失效问题分析及解决方案
-
使用spring声明式事务失效之第二弹
-
使用spring声明式事务失效之第二弹
-
使用spring+springMVC 组合开发,声明式事务失效
-
使用spring+springMVC 组合开发,声明式事务失效
-
Spring MVC @Transactional注解方式事务失效的解决办法
-
分布式事务解决方案:@Transactional注解+log记录操作实现
-
Spring Boot分布式系统实践【基础模块构建3.3】注解轻松实现操作日志记录
-
spring声明事务失效问题
-
spring5 源码深度解析----- @Transactional注解的声明式事物介绍(100%理解事务)