Rocketmq分布式事务提交

原理:执行本地事务之前,先发送一个消息到mq中(该消息只存储在commitlog中,在consumeQueue中不可见,消费端无法看到此消息)。在本地事务执行完毕后,再到达确认(commit)阶段,该阶段主要把半事务消息保存到consumeQueue中,消费者可以看到此消息正常消费,反之是rollback就不保存。

           如本地事务执行时间较长(异步执行),在确认阶段无法及时得到本地事务执行成功的消息。则需要自定义定时执行事务回查机制(默认60s执行一次),如回查到本地事务执行完成的消息后则进行消息正式提交,或进行半事务的消息回滚。

半事务阶段:该阶段主要发一个消息到rocketmq,但此消息只存储在commitlog中,但consumeQueue中不可见,也就是消费端无法看到此消息

确认阶段(commit/rollback):该阶段主要是把半事务消息保存到consumeQueue中,即让消费端可以看到此消息可正常消息,如果是rollback就不保存

事务回查:默认每60s执行回查半事务消息一次,如发现本地事务业务已经成功了,就补发"发送commit确认消息"  复杂业务中可设计一张Transaction表,将业务表和Transaction绑定在同一个本地事务中,如本地事务执行成功时则记录Transaction表的中状态为"已完成",当mq事务回查时,只需检查对应事务的状态是否是"已完成"即可,而无需关心具体的业务数据。

注意点:rockeqmq(几乎所有的消息中间件)不能保障消息的重复(网络波动等原因导致消息被消费了,但offset未提交到mq中),所以在消费端一定要做幂等性处理。

               如果消费端发生消费失败,同时也需要做重试,如果重试多次,消息会进入死信队列,这个时候也需要进行特殊处理。(一般把原业务的执行进行回退)

使用限制:

      1:事务消息不支持延时消息和批量消息

      2:事务回查的间隔时间:BrokerConfig.transactionCheckInterval  通过Broker的配置文件设置

      3:为了避免单个消息被检查太多次而导致半对对列消息累积,默认将单个消息的检查次数限制为15次,可通过broker配置文件的transactionCheckMax参数来修改次限制。如已经检查某条消息超过N次(N=transactionCheckMax)则broker将丢弃此消息,同时打印错误日志。开发可通过重写AbstractTransactionCheckListener类修改这个行为

      4:事务消息在配置文件中的参数transactionMsgTimeout的特定时间长度之后被检查,发送事务消息时,也可通过设置用户属性CHECK_IMMUNITY_TIME_IN_SECONDS来改变这个限制,优于transactionMsgTimeout

      5:事务性消息可能不止一次被检查或消费

      6:事务性消息中用到了生产者群组,是一种高可用机制,用来确保事务消息的可靠性

      7:提交给用户的目标主题消息可能会失败,目前依日志的记录而定,高可用性通过RocketMQ本身的高可用性机制来保证,如希望确保事务消息不丢失,并且事务完整性得到保证,建议使用同步的双重写入机制

      8:事务消息的生产者ID不能与其他类型消息的生产者ID共享。与其他类型的消息不同,事务消息允许反向查询,MQ服务器能通过生产者ID查询到消费者

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值