当前位置:首页 > 公众号精选 > 架构师社区
[导读]Spring项目,需要在一个事务中开启另一个事务。 上面提到的情景可能不常见,但是还是会有的,一旦遇到,如果业务比较复杂,就会很麻烦,但是还是有解决的方案的,比如将一个service方法拆成两个方法,也就是将两个操作的事务分开。 但是这只适用于业务比较简


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的配置中,我们只需要添加标签

Spring 如何在一个事务中开启另一个事务?

并且在代码的调用中要求使用代理对象去调用即可。

End

作者:Mazin , 本文版权归作者所有

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

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:

Spring 如何在一个事务中开启另一个事务?

Spring 如何在一个事务中开启另一个事务?


长按订阅更多精彩▼

Spring 如何在一个事务中开启另一个事务?

如有收获,点个在看,诚挚感谢

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭