谷粒商城 提交订单业务分析

                 提交订单业务分析

思路:去验令牌,创建订单,验价格,远程锁库存,远程扣减积分等整个过程是事务操作。(事务是无法控制远程业务的,需要每个都加事务)

注意:
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 
先了解一下基本知识点,具体代码以后放。

一、本地事务
1 、事务的基本性质
数据库事务的几个特性:原子性 (Atomicity ) 、一致性 ( Consistency ) 、隔离性或独立性 ( Isolation)
和持久性 (Durabilily) ,简称就是 ACID
 
原子性:一系列的操作整体不可拆分,要么同时成功,要么同时失败
 
一致性:数据在事务的前后,业务整体一致。
 
转账。 A:1000 B:1000 ; 转 200
事务成功 ; A 800
B 1200
 
隔离性:事务之间互相隔离。
 
持久性:一旦事务成功,数据一定会落盘在数据库。
在以往的单体应用中,我们多个业务操作使用同一条连接操作不同的数据表,一旦有异常,
我们可以很容易的整体回滚;
Business :我们具体的业务代码
Storage :库存业务代码;扣库存
Order :订单业务代码;保存订单
Account :账号业务代码;减账户余额
比如买东西业务,扣库存,下订单,账户扣款,是一个整体;必须同时成功或者失败
一个事务开始,代表以下的所有操作都在同一个连接里面;
2 、事务的隔离级别
READ UNCOMMITTED (读未提交)
该隔离级别的事务会读到其它未提交事务的数据,此现象也称之为脏读。 READ COMMITTED (读提交)
一个事务可以读取另一个已提交的事务,多次读取会造成不一样的结果,此现象称为不可重
复读问题, Oracle SQL Server 的默认隔离级别。
  REPEATABLE READ (可重复读)
该隔离级别是 MySQL 默认的隔离级别,在同一个事务里, select 的结果是事务开始时时间
点的状态,因此,同样的
select 操作读到的结果会是一致的,但是,会有幻读现象。 MySQL
InnoDB 引擎可以通过
next-key locks 机制(参考下文 " 行锁的算法 " 一节)来避免幻读。
 
SERIALIZABLE (序列化)
在该隔离级别下事务都是串行顺序执行的, MySQL 数据库的 InnoDB 引擎会给读操作隐式
加一把读共享锁,从而避免了脏读、不可重读复读和幻读问题。
3 、事务的传播行为
1 PROPAGATION_REQUIRED 如果当前没有事务,就创建一个新事务,如果当前存在事务,
就加入该事务,该设置是最常用的设置。
2 PROPAGATION_SUPPORTS 支持当前事务,如果当前存在事务,就加入该事务,如果当
前不存在事务,就以非事务执行。
3 PROPAGATION_MANDATORY 支持当前事务,如果当前存在事务,就加入该事务,如果
当前不存在事务,就抛出异常。
4 PROPAGATION_REQUIRES_NEW 创建新事务,无论当前存不存在事务,都创建新事务。
5 PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当
前事务挂起。
6 PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
7 PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,
则执行与 PROPAGATION_REQUIRED 类似的操作。

 

 

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值