分布式事务学习总结(一)

前言

  为啥是总结(一)呢?知识总是在不断的学习,总结。总会跟之前大同小异,总会有所收获,也算是version吧,哈哈。
  在之前大学的时候有做过类似自研mq分布式事务的。参考下面的博客

大概思路

  执行完本地操作,保存一条mysql数据,然后定时去判断状态发到mq进行消费。

缺陷
  当mq不可用时,定时扫数据库的会不断重试,消耗性能~参考rocketmq会先发条half消息,证明mq是可以用的,再进行本地事务。

LCN(XA)

这个没有怎么了解过,强一致性的,性能相对会差一点。
在这里插入图片描述
lcn被誉为不是事务的生产者,只是事务的搬运工,哈哈。就是本地事务一套,大家各自处理,外面再一层事务管理器

seata

他的原理使用统一的事务管理器Transation Manager来控制两个不同事务是提交还是回滚。(了解还不是很深入)

在这里插入图片描述

TCC

Try->Confirm->Cancel(最终一致性

第一步预扣,然后提交,如果有人失败呢就回滚。

相关框架:ByteTcc

RocketMQ事务消息

看下官网介绍

可以将其视为两阶段提交消息实现,以确保分布式系统中的最终一致性。
事务性消息可确保本地事务的执行和消息的发送可以原子方式执行。

官网也有个demo,执行完是不会进行回查的,这里有点奇怪

流程

在这里插入图片描述
细品:先发送half消息,这个是为啥?先问下这位mq先生是否还在?或者有没有问题?有问题就不在进行下去了。
在这里插入图片描述
然后进行本地事务处理,判断返回状态
在这里插入图片描述
交易状态
在这里插入图片描述
  讲道理,如果是Unknown已经会使mq回查才对,结果没有(无论是运行官网的demo还是网上的demo,有知道原因的大佬评论一下)

  根据这个状态最终决定half消息进行rollback还是commit。

芋大神的流程图

在这里插入图片描述
配上链接

TransactionListener

在这里插入图片描述

Springboot实现

@RocketMQTransactionListener

@Component
@RocketMQTransactionListener(txProducerGroup = "product_dajitui")
public class TransactionListenerImpl implements RocketMQLocalTransactionListener {

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(org.springframework.messaging.Message message, Object o) {
        /*try {
            Thread.sleep(1000 * 60 * 20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        return RocketMQLocalTransactionState.UNKNOWN;
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(org.springframework.messaging.Message message) {
        System.out.println("回查" + message);
        return RocketMQLocalTransactionState.COMMIT;
    }
}

txProducerGroup 必须跟你发送事务消息的groupId是一致的。

发送者

	@Resource
    private RocketMQTemplate rocketMQTemplate;

    @GetMapping("/dajitui")
    public void dd() {
        Message<String> message = MessageBuilder.withPayload("dajitui1111111").build();
        TransactionSendResult sendResult = rocketMQTemplate.sendMessageInTransaction("product_dajitui", "DefaultCluster", message, null);
        System.out.println(String.format("send transcation message body=%s,result=%s", message.getPayload(), sendResult.getSendStatus()));
    }

疑问

executeLocalTransaction加上了睡眠,结果还是不会引起mq的回查,太难了。

阿里官网介绍

在这里插入图片描述

自研mq分布式事务

请教了某大佬的自研分布式事务,原理也跟Rocketmq事务原理一样。

  开始讲故事:一开始也有个prepare消息到mq,并且保存状态在数据库里头,简称消息状态标识记录。就是预发状态
  然后进行本地事务,如果成功把标识改成确认,并且发布mq里头。如果说执行失败,标识就结束
  另一种情况,就是数据库是预发状态,但是一直没有动静,可能你应用挂了,网络延迟是吧,所以模拟rocketmq一个事务回查,提供一个回查的接口。定时器定时扫数据库预发状态的数据,进行事务回查,如果本地没有执行完那么就结束,如果执行完了就发送mq。

为啥有回查这一步?

执行本地事务跟mq发布不是原子性的

上面做了那么多是在干嘛的?

为了发送方尽可能的发送成功

那么如何保证消息也是成功?

mq重试->死信->人工处理

最终一致性的体现!

参考博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值