分布式事务

分布式事务#

分布式事务,主要为了实现分布式系统下一组操作的全部成功或全部失败,
主要分为数据库层的和业务层的分布式事务,

一、数据库层的主要是基于XA协议的分布式事务,实现的强一致性,基于XA模型,主要有全局的事务管理器和本地资源管理器,事务管理器会调度本地资源管理器的本地事务的提交和回滚,达到全局的强一致性

二、业务层的,基于CAP和BASE理论,实现的最终一致性,来支持的分布式事务,主要有tcc模型的补偿性事务,tcc模型主要将操作分为三个,try, confirm, cancel, try会预留该事务的资源,即使当前事务出问题,也不会影响其它事务,支持高并发, 当一组服务的try都成功,tcc会保证所有服务的confirm最终成功,如果一组服务中有try失败,tcc会保证所有的服务最终cancel成功。

事务#

核心:修改多个数据时,保证对多个数据操作一致性

如何保证一致性: 两阶段

  • 让失败的部分操作 全部成功 ( x )
  • 让成功的部分操作 全部回退 ( √ )

事务一致性的基本要求#

在提交之前,要保证所有的操作都可以回滚
条件:

  • 对每个操作,要知道如何回滚
  • 为保证能正确回滚,需要控制事务的并发
    在并发场景下,不能让两条rollback之间相互影响
    (可以是阻塞等待,也可以是抛出异常、返回失败。只要能避免事务往不一致的方向发展就好。)

tcc的一致性保证#

cancel/confirm 失败怎么办?– 重试到成功为止
如何重试? – 事务协调器 tc

tc#

TC 是一个独立的服务,用于协调分布式事务内的多个操作一起提交或者回滚。
存储了事务执行的中间状态

rocketMq事务#

先执行 DB 操作,再发消息,难以保证消息一定发出去。

RocketMQ 就反过来,先发一个半消息(Half Msg,类似一个 Prepare 操作),这个半消息是不会投递给消费者的,半消息发送成功再执行 DB 操作,DB 操作成功以后,提交半消息,这个时候半消息就变成一个普通消息送到消费者那里。

对于 RocketMQ 消费者而言,事务消息和非事务消息是没有区别的。

  1. 第 1 步发生异常,半消息发送失败,那么本地 DB 事务根本就不会执行,整个操作失败了,但是 DB/消息的状态是一致的(都没有提交)。
  2. 第 2 步发生异常,或者返回超时,生产者以为失败了,因此 DB 操作不会执行,也就没有后续了。另一边 Broker 存储半消息成功了,
    却迟迟等不到后续的提交操作,等了好久(超时)以后,Broker 就会跑来问生产者(回查,也就是第 4 步),这个半消息到底是要提交还是回滚?
    此时生产者去数据库中确认本地 DB 事务的完成状态(第 6 步),给 Broker 一个回答(第 7 步),然后 Broker 就知道要怎么办。
  3. 第 3 步 DB 操作失败,生产者可在第 4 步,告知 Broker 回滚半消息。另外生产者也可以报告状态为”未知”,然后由 Broker 稍后触发回查来决定提交还是回滚半消息。
  4. 第 4 步提交/回滚半消息失败,Broker 等不到这个操作,会在一段时间以后触发回查,与上面的第 2 步异常类似。
  5. 第 5、6、7 步回查失败,如果回查发生异常或者回查仍然返回”未知”,或回查失败,RocketMQ 稍后会重新调度,最多会回查 15 次

tcc和rocketMq事务的比较#

tcc优势

  1. rpc事务,将多个rpc组合在一起
  2. tcc可以无限去加更多的操作来判断整体的提交或回滚。事务中的操作有3个及以上,要根据其中的结果判断是否要回滚其中的前两个,这种rocketmq就无法去做。(rocketmq 比较被动,当本地事务提交了,后面的一定要提交,缺少判断多个操作的结果来判断整体是否提交的能力)
  3. rocket mq的异步消息在逻辑上一定是成功的,但tcc的其他操作也可以是失败的可以参与到整体成功与否的判断的。如果rocket mq中的异步操作不一定会成功不能使用rocket mq
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×