提交订单业务分析
思路:去验令牌,创建订单,验价格,远程锁库存,远程扣减积分等整个过程是事务操作。(事务是无法控制远程业务的,需要每个都加事务)
注意:
1,《提交订单》按钮页面,既订单结算页,此时设置防重令牌,避免多次提交,每次刷新该页面令牌会变。
2,提交订单首先利用redis的String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";脚本
【令牌的对比和删除必须保证原子性】验证令牌,原子验证令牌和删除令牌
3,保存订单之后,要进行锁库存,避免用户付款的时候出现库存不足的情况;而且库存要是失败了,还要撤销保存订单的逻辑。
问题1:如果库存锁定成功了,但是由于网络超时,导致返回一个超时异常,让其他程序误以为出现异常了会触发之前的步骤“创建订单”订单回滚,库存扣减。
问题2: 位于锁库存之后的业务“远程扣减积分服务”若异常,上面的库存将不会回滚。简单理解就是,远程服务执行完成,下面的其他方法出现问题,导致:已执行的远程请求肯定不能回滚,因为不在一个连接里面,事务没法控制。
查看《本地事务与分布式事务》文档
解决方式1:seatea @GlobalTransactional //高并发 的时候又会出问题,效率极低
Seata控制分布式事务
* 1)、每一个微服务先必须创建 undo_log;
* 2)、安装事务协调器;seata-server: https://github.com/seata/seata/releases
* 3)、整合
* 1、导入依赖 spring-cloud-starter-alibaba-seata seata-all-0.7.1
* 2、解压并启动seata-server;
* registry.conf: 注册中心配置; 修改registry type=nacos
* file.conf:
* 3、所有想要用到分布式事务的微服务使用seata DataSourceProxy代理自己的数据源
* 4、每个微服务,都必须导入
* registry.conf
* file.conf vgroup_mapping.{application.name}-fescar-service-group = "default"
* 5、启动测试分布式事务
* 6、给分布式大事务的入口标注@GlobalTransactional
* 7、每一个远程的小事务用 @Transactional
库存解锁的场景
1)、下订单成功,订单过期没有支付被系统自动取消、被用户手动取消。都要解锁库存
2)、下订单成功,库存锁定成功,接下来的业务调用失败,导致订单回滚。seata效率太慢,不考虑.
之前锁定的库存就要自动解锁。
解决:RabbitMQ
先了解一下基本知识点,具体代码以后放。
![](https://img-blog.csdnimg.cn/20210606202607219.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2Nzc0NzM0,size_16,color_FFFFFF,t_70)