Spring怎么在一个事务中开启另一个事务

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Spring怎么在一个事务中开启另一个事务

点击上方“Java知音”,选择“置顶公众号”

技术文章第一时间送达!

作者:Mazin my.oschina.net/u/3441184/blog/893628

my.oschina.net/u/3441184/blog/893628

Spring项目,需要在一个事务中开启另一个事务。

上面提到的情景可能不常见,但是还是会有的,一旦遇到,如果业务比较复杂,就会很麻烦,但是还是有解决的方案的,比如将一个service方法拆成两个方法,也就是将两个操作的事务分开。

但是这只适用于业务比较简单的,如果出现多次数据库的写操作,而我们调用的系统只需要其中一个写操作的最新数据,如果我们将它分开,那么如果调用目标系统出现异常的时候,那么之前的写操作就不能回滚了。

举个简单的例子:


@Service
public class ServiceA {

    @Transactional
    public void doSomething(){

        向数据库中添加数据;

        调用其他系统;
    }
}

这里就用伪代码来做示例了,当我们执行了“向数据库中添加数据”,我们去数据库中查询,发现并没有我们添加的数据,但是当我们的service这个方法执行完成之后,数据库中就有这条数据了,这是由于数据库的隔离性造成的。

spring中的事务注解@transactional提供了一个参数:


Propagation propagation() default Propagation.REQUIRED;

这个参数是定义spring事务的传递性的,默认值为required,也就是如果有事务,就加入事务,如果没有,就创建事务。这个参数的值有很多,例如REQUIRES_NEW,这个值就代表创建一个新的事务,与原来的事务分开。这个好像能解决我们的问题。

我们将刚刚那个方法修改一下:


@Service
public class ServiceA {

    @Transactional
    public void doSomething(){

        insert();

        调用其他系统;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void insert(){
        向数据库中添加数据;
    }
}

执行之后,发现结果还是没有改变,必须要整体执行完成,数据库中数据才会出现,说明还是在一个事务中。

我们再将代码修改一下:


@Service
public class ServiceA {

    @Autowired
    private ServiceB serviceB;
    @Transactional
    public void doSomething(){

        serviceB.insert();

        调用其他系统;
    }
}

@Service
public class ServiceB {

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void insert(){
        向数据库中添加数据;
    }
}

我们将要事务分离出来的方法写在另一个service中,再次测试,发现执行完插入语句之后,数据库中就已经能查到数据了,说明事务分离了,完成了我们的需求。

当然spring其实也考虑这个,在spring的配置中,我们只需要添加标签  aop:aspectj-autoproxy expose-proxy="true"/ 或者  aop:config expose-proxy="true" ,并且在代码的调用中要求使用代理对象去调用即可:


((ServiceA ) AopContext.currentProxy()).insert();

END

Java面试题专栏

Spring怎么在一个事务中开启另一个事务

我知道你 “在看Spring怎么在一个事务中开启另一个事务

原文始发于微信公众号(Java知音):

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Spring怎么在一个事务中开启另一个事务


 上一篇
在Spring事务管理下,Synchronized为啥还线程不安全? 在Spring事务管理下,Synchronized为啥还线程不安全?
点击上方“后端技术精选”,选择“置顶公众号” 技术文章第一时间送达! 作者: 六脉神剑 juejin.im/post/5ddc7a23e51d452331202721 juejin.im/post/5dd
2021-04-05
下一篇 
理解Spring——IOC的原理及手动实现 理解Spring——IOC的原理及手动实现
点击上方“Java知音”,选择“置顶公众号” 技术文章第一时间送达! 作者:宁愿 juejin.im/post/5c11b1e06fb9a04a0d56b787 juejin.im/post/5c11b1
2021-04-05