事务:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID特性
目前大家所说的分布式事务,更多情况下,是在分布式系统中事务的不完整实现,
分布式事务实现有 2PC(Two-phase Commit,也叫二阶段提交)、TCC(Try-Confirm-Cancel) 和事务消息。
消息队列中的“事务”,主要解决的是消息生产者和消息消费者的数据一致性问题。
事务消息适用的场景主要是那些需要异步更新数据,并且对数据实时性要求不太高的场景。
消息队列通过事务消息来实现分布式事务的
订单系统在消息队列上开启一个事务。然后订单系统给消息服务器发送一个“半消息”,这个半消息不是说消息内容不完整,它包含的内容就是完整的消息内容,半消息和普通消息的唯一区别是,在事务提交之前,对于消费者来说,这个消息是不可见的。
第四步提交事务消息时失败了怎么办?
Kafka 的解决方案比较简单粗暴,直接抛出异常,让用户自行处理。我们可以在业务代码中反复重试提交,直到提交成功,或者删除之前创建的订单进行补偿。
RocketMQ 中的分布式事务实现,增加了事务反查的机制来解决事务消息提交失败的问题。为了支撑这个事务反查机制,我们的业务代码需要实现一个反查本地事务状态的接口,告知 RocketMQ 本地事务是成功还失败。它检查的是本地事务有没有执行成功,并不比较数据是否一致。
TCC
https://www.cnblogs.com/jajian/p/10014145.html
2PC与3PC
https://baijiahao.baidu.com/s?id=1627359666565869408&wfr=spider&for=pc
RocketMQ的事务适用于解决本地事务和发消息的数据一致性问题,事务反查机制
kafka的事务则是用于实现它的exactly once机制,应用于实时计算,解决“读数据-计算-保存结果”的过程中数据不重不丢。确保一个事务中发送的多条消息,要么都成功,要么都失败,多条消息不一定要在同一个主题和分区中。
kafka中引入了事务协调者,负责在服务端协调整个事务,它是broker进程的一部分,通过选举保证自身的可用性,kafka集群中,可以存在多个协调者,每个负责管理和使用事务日志(也是一个topic)中的几个分区,提升并行性能,
3.6.1 Producer 事务
为了实现跨分区跨会话的事务,需要引入一个全局唯一的 Transaction ID,并将 Producer获得的PID 和Transaction ID 绑定。这样当Producer 重启后就可以通过正在进行的 TransactionID 获得原来的 PID。为了管理 Transaction,Kafka 引入了一个新的组件 Transaction Coordinator。Producer 就是通过和 Transaction Coordinator 交互获得 Transaction ID 对应的任务状态。TransactionCoordinator 还负责将事务所有写入 Kafka 的一个内部 Topic,这样即使整个服务重启,由于事务状态得到保存,进行中的事务状态可以得到恢复,从而继续进行。
3.6.2 Consumer 事务
上述事务机制主要是从 Producer 方面考虑,对于 Consumer 而言,事务的保证就会相对较弱,尤其时无法保证 Commit 的信息被精确消费。这是由于 Consumer 可以通过 offset 访问任意信息,而且不同的 Segment File 生命周期不同,同一事务的消息可能会出现重启后被删除的情况。