事务(三)、弱一致性事务

书接上回,程序员穷开心通过数据库实现了转账事务的强一致性。沧海桑田,世事变幻,话说李雷又要向韩梅梅转账100元,但事情有了变化。

故事的发展

李雷账户在火星人民银行,韩梅梅搬到了水星,账户在水星人民银行。程序员穷开心在海绵宝第三方支付公司写程序。由于CAP悖论,火星人民银行和水星人民银行都不对外提供二阶段提交事务接口。

老革命遇到了新问题,穷开心决定深入了解下分布式事务的理论知识。

CAP定理(帽子理论)

定理:任何分布式系统只可同时满足CAP二点,没法三者兼顾。[参考][2]

  • C:Consistency,一致性, 数据一致更新,所有数据变动都是同步的
  • A:Availability,可用性, 好的响应性能,完全的可用性指的是在任何故障模型下,服务都会在有限的时间处理响应
  • P:Partition tolerance,分区容错性,可靠性

关系型数据库由于关系型数据库是单节点的,因此不具有分区容错性,但是具有一致性和可用性,而分布式的服务化系统都需要满足分区容错性,那么我们必须在一致性和可用性中进行权衡,具体表现在服务化系统处理的异常请求在某一个时间段内可能是不完全的,但是经过自动的或者手工的补偿后,达到了最终的一致性。

BASE模型

BASE模型不同于ACID模型,通过牺牲高一致性获得可用性或可靠性。所以BASE模型也称为弱一致性事务模型,柔性事务模型。BASE模型包含个三个元素:

  • BA:Basically Available,基本可用
  • S:Soft State,软状态,状态可以有一段时间不同步
  • E:Eventually Consistent,最终一致,最终数据是一致的就可以了,而不是时时保持强一致

弱一致性事务模型分为

  • 两阶段型
  • 补偿型
  • 异步确保型
  • 最大努力通知型

在实现方案上,又可以分为:

  • 消息日志方案(异步确保型、最大努力通知型) :本地消息表、MQ(非事务消息)、[MQ(事务消息)][4]
  • 分布式锁方案(两阶段型) :redis、关系数据库行级独占锁、zookeeper
  • 对账补偿方案(补偿型)
  • Saga事务模型
  • TCC事务模型: Try-Confirm-Cancell(补偿型)

Saga事务模型: Long-running-transaction 把一个长事务拆分为多个本地事务来实现,由一个process manager来统一协调。如果成功则继续往下执行,如果失败则调用补偿操作。每个业务都至少要实现正向、负向两个接口。
TCC事务: 针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。

  • Try 阶段主要是对业务系统做检测及资源预留
  • Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即只要Try成功,Confirm一定成功。
  • Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

互联网支付方案

在深入思考(百度)一番后,穷开心决定按如下方案实现火星到水星的转账:

开始
   创建本地支付订单A,订单状态新建。
   请求火星人民银行,检查李雷是否有100元。
   请求火星人民银行,李雷账号减少100元,订单号A。
   更新订单A状态,扣款成功。
   请求水星人民银行,韩梅梅账号pk-=2增加100元,订单号A。
   更新订单A状态,付款成功。
结束

最大努力型

由于整个过程没有ACID事务一致保证,穷开心设计了重试方案:

#//当李雷账号完成扣款,请求水星人民银行异常时进入
开始
   检查本地支付订单A状态为扣款成功的订单。
   检查订单是否超过重试次数,如果超过则更新订单为异常失败单。
   增加订单重试次数。
   请求水星人民银行, 检查订单A状态。
   请求水星人民银行,韩梅梅账号pk-=2增加100元,订单号A。
   更新订单A状态,付款成功。
结束

由于超过重试次数等原因,异步确保方案依然无法实现最终一致性,幸好银行都提供了对账文件,穷开心又写了对账方案,确保订单最终完成。

事务补偿型

李雷在向韩梅梅转账时,韩梅梅以为卡被盗了,打电话要求银行冻结自己的银行账号;银行当然满足了上帝的要求。

在ACID模型中,事务内的单个逻辑单元要么全部成功要么全部失败。但在BASE模型中,穷开心的方案只能保证全部成功,如果某个逻辑单元无论如何都无法成功时,需要有其他机制保证已经完成的逻辑单元能够退回到执行前的状态。已经完成的逻辑单元不能直接通过回滚的方式删除记录,否则无法对账核实。幸好银行非常体贴的提供了一个新交易类型–“冲正”。

  • 冲正是为系统认为可能交易失败时采取的补救手法。在银行业务中,冲正是对一笔正交易的反交易。

在发现李雷扣款成功,系统已经明确无法完成向韩梅梅付款时,穷开心设计发起冲正交易

#//当李雷账号完成扣款,请求水星人民银行异常时进入
开始
   检查创建本地冲正订单B,对应支付订单A。
   请求水星人民银行, 请求冲正交易。
   新建事务
   更新订单A状态,冲正成功。
   更新订单B,冲正成功
   结束事务
结束

整理一下,银行为海绵宝至少提供了以下服务:

  1. 扣款接口
  2. 收款接口
  3. 订单查询接口
  4. 冲正接口
  5. 对账文件

参考:
[1]: https://www.jianshu.com/p/1156151e20c8 “分布式服务化系统一致性的“最佳实干””
[2]: https://www.jdon.com/37625 "CAP原理和BASE思想 "
[3]: https://kaimingwan.com/post/fen-bu-shi/fen-bu-shi-shi-wu-de-dian-xing-chu-li-fang-shi-2pc-tcc-yi-bu-que-bao-he-zui-da-nu-li-xing "分布式事务的典型处理方式:2PC、TCC、异步确保和最大努力型 "
[4]: https://www.jianshu.com/p/53324ea2df92 "RocketMQ实战(三):分布式事务 "
[4]: https://www.jianshu.com/p/e4b662407c66 “分布式事务:Saga模式”

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值