当前位置: 首页 > news >正文

商城系统分布式下单

一、锁定库存的sql
select * from ware where id={id} and total-lock>0
update ware set lock=lock+{num} where id={id} and total-lock>={num}
二、下单服务要用分布式事务,因为seat的二阶段提交要说很多资源,会造成处理变成串行化,高并发下不使用,采用柔性事务+消息队列最终一致化方案

到这里终于懂了,采用柔性事务+消息队列最终一致化方案就是当事务中的某一个操作失败后,采用消息队列补偿机制,通过发送消息将执行的操作进行反省操作 达到回滚的目的。
这里有两种方案:一、当try操作失败以后,在catch中发送一条消息,消息处理方收到消息以后,将数据还原
二、在try的时候,直接发送一条消息,而不是登发生异常以后再发送,这条消息是发到延迟队列的,这样做的好处是,不用再catch中做补偿了,延时队列中的消息到时间以后,判断数据状态,需要补偿的进行数据的回滚,不需要的直接忽略。

三、采用延时队列的好处,可以实现自动关单的功能同时还能实现消息补偿

其实分布式事务 就是把原先在一个方法中的事务 分到了不同的服务中,这个时候就要考虑,这个时候就要考虑被调用方 和调用方 发生错误回滚的不同情况,

@Transactional
public void test (){save(classA);feginB();feginC();feginD();
}
@Transactional
public R feginB(){
doService()
sendMessage();
}
@Transactional
public R feginC(){
doService()
sendMessage();
}
@Transactional
public R feginD(){
doService()
sendMessage();
}

fegin中的消息队列就是为了fegin事务回滚用的
比如feginC()发生错误,这时候需要回滚feginB,这时候可以采用在test()方法中catch异常然后发送消息,进行数据的补偿回滚,我们采用在fegin主动调用延时队列的方式,就不用catch了,并且还可以做到期自动关单
发送消息是为了回滚,需要新增表专门记录需要回滚的数据id是哪个,回滚数据的值为哪些。
为什么延迟队列用能做到期自动关单呢,其实把下单逻辑当成一个大事务来看,feginD就是支付方法,到期未支付就是fefinD发生异常,所以也需要发送消息就行数据的补偿,和大逻辑就吻合了。

另一个问题feginC中发生了异常,这时候就不能catch异常,必须抛异常使得test方法回滚,因为feginC也是事务方法,所以feginC的方法也回滚了。如果feginC中是循环发送消息的,也没关系,因为消息记录表中的数据也回滚了,当处理消息的时候 在消息记录表中查不到数据,也不会过多处理。这里发送消息的时候处理发送消息记录表中的id,最好把主表的相关数据也传过去,要不然容易造成主表记录没有回滚

解锁库存 三种情况
1、到期自动关单
2、用户手动关单
3、因为调用feginC失败,需要将feginB回滚

一个事务中调用fegin fegin也是一个事务,并且fegin中调用了消息队列

相关文章:

  • 【Spring Boot 源码学习】JedisConnectionConfiguration 详解
  • 软磁直流测试系统电参量指标
  • 【论文阅读】Generating Radiology Reports via Memory-driven Transformer (EMNLP 2020)
  • 基于Skywalking的全链路跟踪实现
  • 电机应用-直流有刷电机
  • 1212. 地宫取宝
  • 【解决问题】---- 解决 avue-crud 表格勾选数据翻页后界面保持选中
  • 使用PE U盘在VM Workstation中安装系统
  • 二十、泛型(4)
  • 【PTE-day06 文件上传】
  • Spring boot集成sentinel限流服务
  • react typescript @别名的使用
  • 【面经】讲一下线程池的参数和运行原理
  • Flutter IOS 前后台切换主题自动变化的问题
  • 鸿蒙列表,类似于安卓的RecyclerView
  • hexo+github搭建个人博客
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 【技术性】Search知识
  • canvas 五子棋游戏
  • emacs初体验
  • es6
  • ES6 ...操作符
  • Git初体验
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • JDK 6和JDK 7中的substring()方法
  • laravel 用artisan创建自己的模板
  • mysql外键的使用
  • NSTimer学习笔记
  • PHP面试之三:MySQL数据库
  • Vue2.0 实现互斥
  • Yeoman_Bower_Grunt
  • yii2权限控制rbac之rule详细讲解
  • 分布式任务队列Celery
  • 给Prometheus造假数据的方法
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 区块链共识机制优缺点对比都是什么
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 微信小程序:实现悬浮返回和分享按钮
  • 用quicker-worker.js轻松跑一个大数据遍历
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • 阿里云服务器购买完整流程
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • $$$$GB2312-80区位编码表$$$$
  • (23)Linux的软硬连接
  • (JS基础)String 类型
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (二)JAVA使用POI操作excel
  • (二)springcloud实战之config配置中心
  • (二)斐波那契Fabonacci函数
  • (二十四)Flask之flask-session组件
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)ssm码农论坛 毕业设计 231126
  • (力扣题库)跳跃游戏II(c++)