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

 更新时间:2021年11月15日 11:44:54   作者:秋天的春  
这篇文章主要为大家介绍了分析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中嵌套事务失效分析的资料请关注脚本之家其它相关文章!

相关文章

  • Swagger实现动态条件注入与全局拦截功能详细流程

    Swagger实现动态条件注入与全局拦截功能详细流程

    这篇文章主要介绍了Swagger实现动态条件注入与全局拦截功能详细流程,Swagger 可以提供 API 操作的测试文档,本文记录 Swagger 使用过程中遇到的小问题
    2023-01-01
  • spring boot教程之建立第一个HelloWorld

    spring boot教程之建立第一个HelloWorld

    这篇文章主要介绍了spring boot教程之建立第一个HelloWorld的相关资料,需要的朋友可以参考下
    2022-08-08
  • JavaEE通过response实现请求重定向

    JavaEE通过response实现请求重定向

    这篇文章主要介绍了JavaEE通过response实现请求重定向的方法,非常的简单实用,有需要的朋友可以参考下
    2014-10-10
  • Java轻量级权限认证框架Sa-Token的使用

    Java轻量级权限认证框架Sa-Token的使用

    Sa-Token是一个轻量级Java权限认证框架,本文就详细的来介绍一下Java轻量级权限认证框架Sa-Token的使用,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权等,感兴趣的可以了解一下
    2022-03-03
  • Java C++实现相同MD5加密算法的方式

    Java C++实现相同MD5加密算法的方式

    这篇文章主要介绍了Java与C++实现相同MD5加密算法的方法,需要的朋友可以参考下面文章内容
    2021-09-09
  • Hadoop源码分析六启动文件namenode原理详解

    Hadoop源码分析六启动文件namenode原理详解

    本篇是Hadoop源码分析系列文章第六篇,主要介绍Hadoop中的启动文件namenode,后续本系列文章会持续更新,有需要的朋友可以借鉴参考下
    2021-09-09
  • Java异常处理原理与用法实例分析

    Java异常处理原理与用法实例分析

    这篇文章主要介绍了Java异常处理原理与用法,结合实例形式分析了Java异常处理相关概念、原理、用法及操作注意事项,需要的朋友可以参考下
    2020-04-04
  • java代码获取UUID的实现示例

    java代码获取UUID的实现示例

    本文主要介绍了java代码获取UUID的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • mybatis映射文件操作存储过程的实现

    mybatis映射文件操作存储过程的实现

    本文主要介绍了mybatis映射文件操作存储过程的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • SpringDataJpa写原生sql遇到的问题及解决

    SpringDataJpa写原生sql遇到的问题及解决

    这篇文章主要介绍了SpringDataJpa写原生sql遇到的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11

最新评论