分析Springboot中嵌套事务失效原因详解
首先两个事务方法,其中一个调用另一个。
@Transactional(rollbackFor = Exception.class) public void trance() { try { trance1();//调用下一个事务方法。 } catch (Exception e) { e.printStackTrace(); } User user = new User(); ShardingIDConfig shardingIDConfig = new ShardingIDConfig(); user.setId(shardingIDConfig.generateKey().longValue()); user.setName("trance"); user.setSex(0); userMapper.create(user); } @Transactional(propagation = Propagation.REQUIRED) public void trance1() throws Exception{ User user = new User(); ShardingIDConfig shardingIDConfig = new ShardingIDConfig(); user.setId(shardingIDConfig.generateKey().longValue()); user.setName("trance1"); user.setSex(1); userMapper.create(user); System.out.println(user.getId()); throw new RuntimeException(); }
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
然后写个测试类,我也是第一次用这个测试
import com.lijia.App; import com.lijia.service.UserService; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) public class Test { @Autowired private UserService userService; @org.junit.Test public void trance(){ userService.trance(); } }
执行会发现报了RuntimeException,但是数据库里面有两条数据,说明事务失效了
runtimeException
数据库两条数据都上传了,说明事务失效
为什么会出现这种情况呢
spring事务使用了动态代理。还是从动态代理去看。
给出一段代码
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface IHello { public void test(); public void test1(); } class Hello implements IHello{ @Override public void test() { System.out.println("test"); } @Override public void test1() { System.out.println("test1"); } } public class MyInvoke implements InvocationHandler{ public Object target; public MyInvoke(Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().contains("test")){ System.out.println("========代理了======="); } return method.invoke(target,args); } public static void main(String[] args) { MyInvoke myInvoke = new MyInvoke(new Hello()); IHello iHello = (IHello) Proxy.newProxyInstance(MyInvoke.class.getClassLoader(),new Class[]{IHello.class},myInvoke); iHello.test(); iHello.test1(); } }
将上面的Hello类
中的test1方法
放入test方法
中
public void test() { test1(); System.out.println("test"); }
回到上面的问题,会发现trance1()
没有走代理,所以会出现两个都插入数据库的操作。
那么需要得到当前的代理对象,然后调用trance1()
通过AopContext.currentProxy()
获得当前代理
((UserService)AopContext.currentProxy()).trance1();
改成这样调用trance1()
运行Test,然后数据库就剩一条数据了,说明trance1()
方法回滚了。
以上就是分析Springboot中嵌套事务失效原因详解的详细内容,更多关于Springboot中嵌套事务失效分析的资料请关注脚本之家其它相关文章!
相关文章
springBoot整合shiro如何解决读取不到@value值问题
这篇文章主要介绍了springBoot整合shiro如何解决读取不到@value值问题,具有很好的参考价值,希望对大家有所帮助,2023-08-08IDEA配置maven环境的详细教程(Unable to import maven project报错问题的解决)
这篇文章主要介绍了IDEA配置maven环境的详细教程(Unable to import maven project问题的解决),本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-06-06Java面试题之HashMap 的 hash 方法原理是什么
那天,小二去蔚来面试,面试官老王一上来就问他:HashMap 的 hash 方法的原理是什么?当时就把裸面的小二给蚌埠住了,这篇文章将详细解答该题目2021-11-11idea install 时提示jdk的某个jar包的包不存在的问题
这篇文章主要介绍了idea install 时提示jdk的某个jar包的包不存在的问题,本文给大家分享解决方法,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-09-09SpringBoot2零基础到精通之profile功能与自定义starter
SpringBoot是一种整合Spring技术栈的方式(或者说是框架),同时也是简化Spring的一种快速开发的脚手架,本篇让我们一起学习profile功能与自定义starter2022-03-03
最新评论