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

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

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

举个简单的例子:

@Service
public class ServiceA {@Transactionalpublic void doSomething(){向数据库中添加数据;调用其他系统;}
}

这里就用伪代码来做示例了,当我们执行了“向数据库中添加数据”,我们去数据库中查询,发现并没有我们添加的数据

但是当我们的service这个方法执行完成之后,数据库中就有这条数据了,这是由于数据库的隔离性造成的。

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

Propagation propagation() default Propagation.REQUIRED;

这个参数是定义spring事务的传递性的,默认值为required,也就是如果有事务,就加入事务,如果没有,就创建事务。

这个参数的值有很多,例如REQUIRES_NEW,这个值就代表创建一个新的事务,与原来的事务分开。这个好像能解决我们的问题。

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

@Service
public class ServiceA {@Transactionalpublic void doSomething(){insert();调用其他系统;}@Transactional(propagation = Propagation.REQUIRES_NEW)public void insert(){向数据库中添加数据;}
}

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

我们再将代码修改一下:

@Service
public class ServiceA {@Autowiredprivate ServiceB serviceB;@Transactionalpublic void doSomething(){serviceB.insert();调用其他系统;}
}
@Service
public class ServiceB {@Transactional(propagation = Propagation.REQUIRES_NEW)public void insert(){向数据库中添加数据;}
}

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

当然spring其实也考虑这个,在spring的配置中,我们只需要添加标签

或者

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

End

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

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

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

长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

Spring 如何在一个事务中开启另一个事务?相关推荐

  1. spring中怎么让事物提交_Spring怎么在一个事务中开启另一个事务

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 作者:Mazin my.oschina.net/u/3441184/blog/893628 ...

  2. 在事务方法中调用另外一个事务方法,被调用方法的事务没起作用

    在事务方法中调用另外一个事务方法,被调用方法的事务没起作用 在事务方法中调用另外一个事务方法,被调用方法的事务没起作用 问题描述:(例) service层有两个事务方法insertUser1.inse ...

  3. java如何在一个Action中调用另外一个Action

    java如何在一个Action中调用另外一个Action /*** 通过远程调用其他系统里的URL获取数据的方法** @param path 需要调用远程的URL地址* @return 返回的是调用U ...

  4. php引入类的位置,php如何在一个类中引入另外一个类

    有时候需要在一个类中调用另外一个类里面的方法,然后另外一个类又需要调用当前类的方法,怎么办呢?下面是具体的介绍.希望对大家有用,更多内容请关注应届毕业生网! 可以直接引入类对象的方式调用另外一个类的方 ...

  5. python 调用另一个py_跟我自学python 第9章 类(9.4.6 在一个模块中导入另一个模块)...

    大家好今天学习9.4.6 在一个模块中导入另一个模块 .今天我们继续学习python.马上类就学完了. 喜欢python就关注冠山巡山使. 我将跟大家一块自学完python语言. 9.4.6 在一个模 ...

  6. android addview指定位置,Android开发中,请问当在一个视图中addView另一个布局视图时为什么报错?...

    Android开发中,我在一个视图中addView另一个布局视图(该视图通过inflate加载获得,其中root为null即没有附加parent视图),为什么还是会报错误: The specified ...

  7. 在一个数组中删除另一个数组存在的值

    在一个数组中删除另一个数组存在的值 可以在购物车中删除多个商品的时候用此方法 在Vuex实现完整购物车中有涉及,详见 Vuex实现完整购物车 <script type="text/ja ...

  8. android 启动一个应用,android 在一个应用中启动另一个应用

    android 在一个应用中启动另一个应用 在程序开发过程当中,常遇到需要启动另一个应用程序的情况,比如在点击软件的一个按钮可以打开地图软件. startDingAppButton = (Button ...

  9. 在一个窗体中调用另一个窗体的控件或方法(C#)

    在一个窗体中调用另一个窗体的控件或方法 解决方案:从构造函数中传递参数(Form). 1.将Form1中的控件改成public属性 具体实现过程请参看一下代码(在form1的textbox1中输入然后 ...

最新文章

  1. UI设计不够高端?这5个小技巧可以试试
  2. 一文了解点特征直方图
  3. pandas UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xb1 in position 0: invalid start byte
  4. python接入微信公众号_Python学习之微信公众号接入 一 验证
  5. docker run常用参数说明
  6. 11-使用NSPersistentContainer搭建CoreData Stack
  7. CPU 可以跑多快?地球到火星的距离告诉你!
  8. (16) Node.js 模块的加载逻辑
  9. java 反射 field get方法_JAVA学习之反射getDeclaredField()方法与getField()方法的区别
  10. 将数据导入excel表格
  11. json替换table下的所有值_京东云所有地域正式支持 MySQL 8.0!
  12. HiveQL学习笔记(三):Hive表连接
  13. 【VRP】基于matalb遗传算法求解多中心的车辆路径规划问题【含Matlab源码 114期】
  14. java dateutils 今天_Java日期时间DateUtils工具包
  15. 子网掩码,可变长子网掩码,ABC类IP网络地址详解
  16. JDK1.8 List转Map
  17. H5(html5)入门教程
  18. vulnhub 网站靶机 DC-1 打靶记录
  19. Android之BroadcastReceiver
  20. css label 居中布局_label标签 html教程

热门文章

  1. D.Digits 思维dp 取log乘积变成加法
  2. centos 7安装mysql_Linux Centos7 下安装Mysql - 8.0.15
  3. java web常用权限方式,java web项目的几种权限控制方法
  4. jsp与java_JSP与JavaBeans
  5. 【每日DP】day3 P1387 最大正方形(奇怪的DP增加了 / 二维前缀和)难度⭐⭐★
  6. poj1274(二分图匹配)
  7. android视频拷到iphone6s,爱思助手怎么把电脑视频导入iphone6s
  8. wamp php非线程安全,wampserver PHP多版本切换
  9. vue如何配置服务器端跨域_vue开发环境配置跨域,一步到位
  10. 程序员心中都有一个江湖,java世界,就是一个江湖!