TCC 强一致性 实时 DEMO 下单(创建订单,扣除库存,增加积分,扣除余额)

伪代码

场景

用购买某种商品1件(原库存1000),增加20积分,扣除100元余额

设计说明

通过日志表来完成TCC。修改库存,余额表要先添加一条记录到他们的日志表里,表要记录TCC状态。
通过唯一业务Code去重,保证幂等。
没有抽象一个活动管理器来管理TCC。

服务

  1. 本地创建订单服务createOrder
  2. 本地插入订单Mapper层 insertOrder(orderCode)
  3. 本地其他服务
  4. 远程服务是否可以扣除库存ifReduceStock(orderCode,reduceNumber)
  5. 远程服务是否可以扣除余额ifReduceBalance(orderCode,sum)
  6. 远程服务Try扣除库存,锁住扣除库存tryReduceStock(orderCode,reduceNumber)
  7. 远程服务Try扣除余额,锁住扣除余额tryReduceBalance(orderCode,sum)
  8. 远程服务增加积分
  9. 远程服务Confirm扣除库存confirmReduceStock(orderCode,ReduceNumber)
  10. 远程服务Confirm扣除余额ConfirmReduceBalance(orderCode,sum)
  11. 远程服务Cancel扣除库存,取消占有资源cancelReduceStock(orderCode,ReduceNumber)
  12. 远程服务Cancel扣除余额,取消占有资源cancelReduceBalance(orderCode,sum)
  13. 远程服务增加积分
  14. 远程其他服务
    补充服务:扣除日志超过timeOut时间的记录状态设置为失效Cancel(在是否扣除ifReduce,Confirm操作中调用补充服务)

创建订单服务createOrder描述

TCC 强一致性 实时 DEMO 下单(创建订单,扣除库存,增加积分,扣除余额)_第1张图片
图1:创建订单-活动图

触发:用户点击下单

本地,检查

  1. 本地业务服务事务开始
  2. 本地业务服务同步检查(调用远程服务是否可以扣除库存ifReduceStock(orderCode,reduceNumber), 远程服务是否可以扣除余额ifReduceBalance(orderCode,sum),其他)
    调用远程服务是否可以扣除库存ifReduceStock(orderCode,reduceNumber)说明:
    首先,要调用补充服务把日志中超过timeOut时间的记录状态设置为失效Cancel。
    其次,要把日志状态为锁住Try库存从剩余库存剪掉
    余额同上
  3. 生成订单Code(orderCode全世界唯一)
  4. 同步本地业务插入订单Mapper层 insertOrder(orderCode),得到订单
  5. 其他本地业务

Try

  1. 同步调用远程服务Try扣除库存tryReduceStock(orderCode,reduceNumber),锁住扣除库存1
    具体:
    远程添加此次扣除日志(三种方式:数据库,Redis,MongoDB),其他判断是否可以扣除库存务必减去这个库存1(从扣除日志找orderCode相同,状态为锁住Try的操作库存数)
    数据记录主要字段,值:
    orderCode(用于去重)
    原库存,值1000
    此次操作库存,值1
    操作时间(一个用途,用于计算超过某个值timeOut后,把此条记录状态设置为失效Cancel)
    状态(锁住Try,确认Confirm,失效Cancel),值锁住Try

  2. 同步调用远程服务Try扣余额tryReduceBalance(orderCode,sum),锁住扣除余额100
    具体同库存

  3. 同步调用远程服务Try增加积分
    具体同库存(比库存简单一些)
  4. 有任何错误或者异常回滚本地事务。结束。

Confirm,Cancel

  1. 同步调用远程服务Confirm真正扣除库存confirmReduceStock(orderCode,ReduceNumber)
    具体:
    首先,要调用补充服务把日志中超过timeOut时间的记录状态设置为失效Cancel
    其次,扣除日志里找到orderCode,此次操作库存为ReduceNumber1,状态为锁住Try记录,根据此条记录扣减库存。
  2. 失败了。1)Cancel扣除库存,取消占有资源2)回滚本地事务。结束。
  3. 同步调用远程服务Confirm扣除余额ConfirmReduceBalance(orderCode,sum)
  4. 失败了。
    1)Cancel扣除余额,取消占有资源
    2)远程调用服务Cancel扣除库存cancelReduceStock(orderCode,ReduceNumber)还原库存
    具体还原库存:
    除日志里找到orderCode,此次操作库存为ReduceNumber1,状态为确认Confirm记录,根据此条记录还原库存。
    3)回滚本地事务。结束。
  5. 同步远程调用增加积分如果失败同样要还原库存和余额
  6. 本地业务服务事务结束,提交。

问题

1.为什么有些地方可以不进行Cancel操作?因为超过TimeOut会Cancel。
2.秒杀活动等高并发怎么办?秒杀情况下,应在下单前的购买和加入购物车操作做限制。添加一个队列,队列中请求已把库存买光,就不允许进入队列走下单。只有进入队列的才可以下单。使用Redis实现。

你可能感兴趣的:(SOA,服务化,微服务,一致性,分布式事务,TCC,强一致性,实时,下单)