分析Springboot中嵌套事务失效原因详解

网友投稿 712 2022-11-22

分析Springboot中嵌套事务失效原因详解

分析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(shardingIDConhttp://fig.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();

}

添加依赖

org.springframework.boot

spring-boot-starter-test

test

然后写个测试类,我也是第一次用这个测试

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() {

http:// 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 = bBdfQflmOPtarget;

}

@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);

}http://

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中嵌套事务失效原因详解的详http://细内容,更多关于Springboot中嵌套事务失效分析的资料请关注我们其它相关文章!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:为什么Spring Boot项目引入依赖的时候可以不指定依赖的版本号
下一篇:Docker中部署tomcat容器(三)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~