分布式事务

1. 2PC(两阶段提交)

1.1 原理

  • 两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段和提交阶段
  • 准备阶段:事务管理器给每个参与者发送prepare消息,每个数据库参与者在本地执行事务,并在写本地的undo/redo日志,此时事务没有提交(但需要锁定资源)
  • 提交阶段:如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚消息;否则发送提交消息。

1.2 缺点

  • 同步阻塞问题:执行过程中,所有参与节点都是事务阻塞型的。数据库本地事务只有在第二阶段(提交阶段)才会进行提交或回滚。(性能差
  • 单点故障问题:协调者发生故障,则参与者会一直阻塞下去。或者提交阶段发生错误,则会导致有些参与方的回滚和提交无法完成,从而造成数据不一致性或者参与方一直锁定资源不释放。
  • 适用于分布式数据库层面的事务,但是不适合业务层面的分布式事务。

1.3 Seata实现的2PC特点

  • seata会在数据库中创建一个undo_log表
  • 准备阶段就会将本地事务给提交。在写数据的同时也会写undo_log表。因为是在本地事务中的,所以保证了写数据和写undo_log表是原子性操作。
  • 在提交阶段,如果事务管理器收到了参与者执行失败或者超时消息时,会给每个参与者发送回滚消息,回滚是通过根据undo_log表中的记录反向更新数据; 否则发送提交消息,即删除undo_log表中的相关记录。
  • 主要解决了传统2PC长期锁资源的问题。

2. TCC

2.1 概念

  • TCC分为三个阶段
  • Try阶段:业务检查一致性或者资源预留。
  • Confirm阶段:Try阶段所有的分支事务都成功后会执行Confirm。通常情况下,采用TCC则任务Confirm阶段是不会出错的。所以只要Try成功,Confirm就一定要成功,如果Confrim不成功,需要进行重试,重试还不行就要进行人工处理。
  • Cancel阶段:在业务执行错误需要回滚的状态下,执行分支事务的业务取消了,需要进行资源释放。通常采用TCC则认为,若Try失败后则Cancel阶段也是一定要成功的。如果Cancel不成功,需要进行重试,重试还不行就要进行人工处理。

2.2 优点

  • TCC不存在资源阻塞问题,因为这三个方法都是直接进行本地事务的提交的。一旦出现异常则通过Cancel来进行回滚补偿。也就是常说的补偿性事务。
  • 因为是在业务层面上实现的,所以TCC可以跨数据库,跨不同的业务系统来实现事务。

2.3 缺点

  • TCC对业务的代码侵入较大和业务紧耦合。需要考虑空回滚,幂等,悬挂等问题。
    • 空回滚:try没执行就调用cancel方法,常常因为分支事务所在服务宕机,解决方法时要识别出这个空回滚,如在try方法里插入一条特殊记录,表示try阶段执行了。然后在cancel阶段去读取该记录,若存在,则正常回滚,否则进行空回滚
    • 悬挂:Cancel接口比Try接口先执行;解决方法:在try也要判断,是否Cancel已经执行了,如果执行了则这个阶段也啥也不做。

3. 可靠消息最终一致性

3.1 概念

  • 当事务发起方执行完成本地事务后并发出一条消息,事务参与方(消息消费者)一定能够接收消息并处理事务成功,此方案强调的是只要消息发给事务参与方最终事务要达到一致

3.2 需要解决的问题

  • 本地事务与消息发送的原子性问题:解决办法是不直接发送给mq,而是打日志数据库。然后定时任务去扫描日志数据库去发送消息
  • 事务参与方接收消息的可靠性:事务参与方必须一定能够收到消息,如果接收消息失败可以重复接收消息。解决办法通过消息队列的ack机制
  • 消息重复消费的问题:事务参与方消费消息需要保证幂等性。

3.3 解决方案一:本地消息表方案

  • 本地事务保证数据业务操作和日志消息操作的原子性,然后通过定时任务将消息发送至消息中间件,待确认消息发送给消费方成功再将日志消息删除

3.4 解决方案二:RocketMQ事务消息方案

  • RocketMQ4.3后实现了完整的事务消息,实际上其实是对本地消息表的一个封装,将本地消息表移动到了MQ内部,解决 Producer 端的消息发送与本地事务执行的原子性问题
  • 发送方在本地事务中,向mq中发送半消息(目前处于不可投递状态),收到mq的ack后,再执行并提交本地事务。
  • 发送方提供事务回查接口,mq会定时调用该接口反查事务状态。mq根据该接口返回的结果来决定要否要投递消息。

4. 最大努力通知

4.1 概念

  • 被调用方会经最大努力向调用方发送通知。(通过消息重试通知机制)
  • 如果实在通知不到,被调用方还提供了查询接口,调用方可以主动调用查询接口来得到结果。
  • 最大努力通知需要提供以下功能
    • 消息重复通知机制
    • 消息校对机制

4.1 最大努力通知与可靠消息最终一致性区别

  • 解决方案思想不同
    • 可靠消息一致性,是由发送方保证将消息发出去,并且将消费发送到接收方。消息的可靠性关键由发送方来保证
    • 最大努力通知,发送方只是尽最大努力将业务处理结果通知给接收方,但是可能消息接收不到,此时需要接收通知方主动调用发起通知方的接口查询业务处理结果,通知的可靠性关键在接收通知方。
  • 两种的业务场景不同
    • 可靠消息一致性,一般用于交易过程,以异步的方式完成交易
    • 最大努力通知,一般用于交易后的通知事务
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值