分布式——事务

解决方案

TCC

场景:假设用户A用他的账户余额给用户B发一个100元的红包,并且余额系统和红包系统是两个独立的系统。

  • Try
    ​创建一条转账流水,并将流水的状态设为交易中
    将用户A的账户中扣除100元(预留业务资源)
    Try成功之后,便进入Confirm阶段
    Try过程发生任何异常,均进入Cancel阶段

  • Confirm
    向B用户的红包账户中增加100元
    将流水的状态设为交易已完成
    Confirm过程发生任何异常,均进入Cancel阶段
    Confirm过程执行成功,则该事务结束

  • Cancel
    将用户A的账户增加100元
    将流水的状态设为交易失败

消息事务+最终一致性

消息事务就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功成功并且对外发消息成功,要么两者都失败。

具体原理如下:

  1. A系统向消息中间件发送一条预备消息
  2. 消息中间件保存预备消息并返回成功
  3. A执行本地事务
  4. A发送提交消息给消息中间件

通过以上4步完成了一个消息事务。对于以上的4个步骤,每个步骤都可能产生错误,下面一一分析:

  • 步骤一出错,则整个事务失败,不会执行A的本地操作
  • 步骤二出错,则整个事务失败,不会执行A的本地操作
  • 步骤三出错,这时候需要回滚预备消息,怎么回滚?答案是A系统实现一个消息中间件的回调接口,消息中间件会去不断执行回调接口,检查A事务执行是否执行成功,如果失败则回滚预备消息
  • 步骤四出错,这时候A的本地事务是成功的,那么消息中间件要回滚A吗?答案是不需要,其实通过回调接口,消息中间件能够检查到A执行成功了,这时候其实不需要A发提交消息了,消息中间件可以自己对消息进行提交,从而完成整个消息事务

基于消息中间件的两阶段提交往往用在高并发场景下,将一个分布式事务拆成一个消息事务(A系统的本地操作+发消息)+B系统的本地操作,其中B系统的操作由消息驱动,只要消息事务成功,那么A操作一定成功,消息也一定发出来了,这时候B会收到消息去执行本地操作,如果本地操作失败,消息会重投,直到B操作成功,这样就变相地实现了A与B的分布式事务

风险:如果B一直执行不成功,那么一致性会被破坏

猜你喜欢

转载自blog.csdn.net/lwl2014100338/article/details/107868939