大家好,我是烤鸭:

今天分享的是spring 多线程 事务的实际应用场景:

上一篇讲了大概的原理,主要是针对事务的开始和执行过程(数据库链接,隔离级别,threadlocal线程绑定)。
https://blog.csdn.net/Angry_Mills/article/details/82502288

下面从实际的角度分析一下。

以下场景的演示代码地址:

https://gitee.com/fireduck_admin/demo-mutithread.git

1.  模拟场景

1.1 方法未加 Transactional 注解,new Thread 方式的主子线程 事务提交情况
    主线程和子线程事务分别提交(主线程提交后子线程提交)
    1.2 方法加 Transactional 注解,new Thread 方式的主子线程 事务提交情况
    主线程和子线程事务一起提交

下面只考虑加注解方式的情况
    1.3 主线程正常,子线程异常 
    无论在new Thread 方式的子线程的run方法加不加 Transactional 注解,子线程都是以无事务方式运行
    1.4 采用springboot的 Async 注解,主线程加事务注解,子线程不加事务注解
    主线程和子线程事务一起提交
    1.5 采用springboot的 Async 注解,主线程加事务注解,子线程不加事务注解,子线程异常
    主线程和子线程事务都未提交
    1.6 采用springboot的 Async 注解,主线程加事务注解,子线程加事务注解 @Transactional(propagation = Propagation.REQUIRES_NEW)
    主线程和子线程事务分别提交(子线程提交后主线程提交)
    1.7 采用springboot的 Async 注解,主线程加事务注解,子线程加事务注解 @Transactional(propagation = Propagation.REQUIRES_NEW),子线程异常
    主线程和子线程事务都未提交
    1.8 采用springboot的 Async 注解,主线程加事务注解,子线程加事务注解 @Transactional(propagation = Propagation.REQUIRES_NEW),主线程异常
    主线程未提交和子线程事务提交

总结一下。
    采用 异步注解的时候,配置Propagation.REQUIRES_NEW,主线程和子线程确实是两个不同的事务,分别提交。
    但是对于子线程的异常,却两个都回滚了。子线程由于异常回滚,这个是没问题的。同时将异常抛给主线程,主线程也跟着回滚了。
    我们可以认为多线程的事务是嵌套的,任何子线程的异常都会导致整个事务的事务回滚。
    但是子线程如果执行完没有异常,事务会直接提交,不管主线程是否异常。

2.  实际场景

之前遇到的场景是这样的,用户和我们发起支付是同步接口,这个时候还要请求第三方的支付接口(如支付宝的接口),这时候就有个问题了。
     由于支付的异步回调如此之快,导致用订单号去数据库查找不到数据(数据还没提交入库)。
     同一个service 做这个肯定不行,就想着把入库的操作放到异步方法里做,主要保证调用第三方接口前数据库已经入库了(子线程事务提交)。
     这时候就可以采用 上面 1.7 的做法,子线程比主线程优先提交,但是即便这样也没法保证子线程的执行一定比回调快。

3.  改进

一般第三方的回调接口都有超时时间响应,他不希望你做任何的逻辑处理。只要接收到消息返回 success 即可。
    所以将消息的接受和业务逻辑处理分开,接受到回调后返回成功,同时异步处理业务逻辑。
    如果这个时候还没入库,把回调的唯一标识(订单号和回调参数)放到缓存。
    在子线程入库后也做类似的操作,查询缓存中的订单号是否存在(存在说明回调先到了),再获取回调参数,手动调用一次异步通知。
    当然这种还是有可能出现极端情况,就是 回调方法刚查询完,放缓存/子线程刚入库,获取缓存同时进行。导致缓存中还是存在订单号。
    这种极低概率的问题,可以间隔一段时间跑补偿程序(1h 一次)。

spring 多线程 事务的实际应用场景相关推荐

  1. spring 多线程 事务 源码解析(一)

    大家好,我是烤鸭: 今天分享的是spring 多线程事务源码分析. 环境: spring-jdbc 5.0.4.REALEASE 今天分享一下spring事务的方法,这一篇还没涉及到多线程. 简单说一 ...

  2. spring 多线程事务的问题

    线程不属于spring托管,故线程不能够默认使用spring的事务,也不能获取spring注入的bean 在被spring声明式事务管理的方法内开启多线程,多线程内的方法不被事务控制. 如下代码,线程 ...

  3. 同一个事务里面对同一条数据做2次修改_要我说,多线程事务它必须就是个伪命题!

    这是why技术的第 74 篇原创文章 别问,问就是不行 分布式事务你应该是知道的.但是这个多线程事务...... 没事,我慢慢给你说. 如图所示,有个小伙伴想要实现多线程事务. 这个需求其实我在不同的 ...

  4. Spring的事务管理难点剖析(4):多线程的困惑

    2019独角兽企业重金招聘Python工程师标准>>> 由于Spring的事务管理器是通过线程相关的ThreadLocal来保存数据访问基础设施(也即Connection实例),再结 ...

  5. 详细整理Spring事务失效的具体场景及解决方案

    实际项目开发中,如果涉及到多张表操作时,为了保证业务数据的一致性,大家一般都会采用事务机制:好多小伙伴可能只是简单了解一下,遇到事务失效的情况,便会无从下手,溪源此篇文章给大家整理了一下常见Sprin ...

  6. spring的事务隔离_再深一点:面试工作两不误,源码级理解Spring事务

    原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处. Spring有5种隔离级别,7种传播行为.这是面试常问的内容,也是代码中经常碰到的知识点.这些知识枯燥而且乏味,其中有些非 ...

  7. 说说 Spring 的事务同步管理器

    Spring 将 JDBC 的 Connection.Hibernate 的 Session 等访问数据库的连接或者会话对象统称为资源,这些资源在同一时刻是不能多线程共享的 . 为了让 DAO 或 S ...

  8. java 对线程进行事务控制_Java 多线程事务回滚 ——多线程插入数据库时事务控制...

    背景 日常项目中,经常会出现一个场景,同时批量插入数据库数据,由于逻辑复杂或者其它原因,我们无法使用sql进行批量插入.串行效率低,耗时长,为了提高效率,这个时候我们首先想到多线程并发插入,但是如何控 ...

  9. 数据批处理神器-Spring Batch(1)简介及使用场景

    数据批处理神器-Spring Batch(1)简介及使用场景 tags: springbatch 1.引言 最近使用Spring Batch进行做数据迁移.数据同步.数据批处理等工作,感叹Spring ...

最新文章

  1. 运维监控系统——Zabbix简介
  2. android运动轨迹rungps_android运动轨迹rungps_Android使用百度地图API实现GPS步行轨迹...
  3. 机器人陪你玩“谁是卧底游戏
  4. jQuery的淡入和淡出简单介绍
  5. 全面详细的jQuery常见开发技巧手册
  6. linux命令 su和sudo,Linux中sudo和su的区别
  7. 免校准的电量计量芯片_单相电能表如何校准(单相电能计量芯片+MCU)
  8. 数据库工作笔记003---在Centos中导入sql文件的方法
  9. Vmware在ubuntu虚拟机上安装Vmtools
  10. 面向对象11:向下转型的使用、instanceof关键字、Object类的使用
  11. 脚本重启电信天翼网关
  12. RNA甲基化修饰m6A检测热门技术—MeRIP-seq
  13. shiro的原理理解
  14. 夏雨老师告诉您学习平面设计到底好不好呢?
  15. 计算机二级wps office考试题库,计算机等级考试题库:WPS Office试题
  16. Unity九宫格切割图片 2D Sprite
  17. 和包贷是什么?究竟如何
  18. 安全测试-短信验证码
  19. 基于QT ffmpeg的动态桌面壁纸
  20. AMAZINGPANDAVERSE打造2.0元宇宙生态的能量杠杆

热门文章

  1. 前端学习(2970):div的scoped
  2. [html] iframe如何自动调整高度?
  3. 工作381-兼容移动端头部
  4. [vue] vue常用的修饰符有哪些?列举并说明
  5. 工作323:uni-获取时间参数
  6. [js] 在设置keyup监听事件后按F5刷新和按浏览器中刷新键刷新有什么区别?
  7. 前端学习(2803):点击商品列表导航到商品详情页
  8. 前端学习(2140):webpack的安装
  9. 前端学习(1347):用户的增删改查操作4修改
  10. 第一百三十二期:MySQL系列:一句SQL,MySQL是怎么工作的?