RocketMQ事务消息的最佳实践

在分布式的场景下,我们经常能遇到事务一致性问题,如何去保证事务的一致性,是分布式场景下不可避免的一个重要话题。
我们很难去做到事务的强一致性(有方案),因此会退一步去保证事务的最终一致性。

如何去保证事务的最终一致性呢?我们可以利用RocketMQ的事务消息来保证事务的最终一致性。

RocketMQ如何保证事务的一致性呢?原来,RocketMQ通过将应用本地事务和发送消息操作定义到全局事务中,要么同时成功,要么同时失败。这样就保证了本地事务和消息发送的一致性:

在这里插入图片描述
事务消息的原理可以参考事务消息以及收发事务消息,接下来我们需要将其应用到我们的SpringBoot应用中去。

首先引入RocketMQ的starter依赖(gradle):

    //省略其他依赖
    implementation 'org.apache.rocketmq:rocketmq-spring-boot-stater:2.2.0'

rocketmq-spring-boot-stater提供了Spring环境下的RocketMQ的集成,它使RocketMQ使用起来更加的方便。不同于上述的收发事务消息里的实现,我们可以通过实现RocketMQLocalTransactionListener来简化我们的操作。然后可以可以通过TransactionMQProducer#sendMessageInTransaction来发送消息

通过上述的操作,最终所有的回调都会进入RocketMQLocalTransactionListener#executeLocalTransaction这个方法。然而这样的话,我们如何去做不同的业务,然后提交事务呢?我们注意到sendMessageInTransaction方法的第二个参数是一直透传到executeLocalTransaction方法的第二个参数的,这个参数的作用RocketMQ的解释是与本地事务执行器一起使用的参数,因此我们可以利用这个参数来实现业务操作。

我们设计一个本地事务执行器,将这个执行器作为sendMessageInTransaction的第二个参数,然后就可以在executeLocalTransaction方法里面执行执行器的操作了:

public interface LocalTransactionExecutor<R> {
   
   

    /**
     * 执行本地业务并提交事务
     * @author zhaosheng
     */
    void execute();

    /**
     * 返回结果或抛异常
     * @author zhaosheng
     */
    R getResult() throws Exception;
}

然后提供一个默认的实现:

public class DefaultLocalTransactionExecutor<R> implements LocalTransactionExecutor<R> {
   
   
    private MyException myException;
    private Exception exception;
    private R result;
    private Runnable runnable;
    private Supplier<R> supplier;

    public DefaultLocalTransactionExecutor(Runnable runnable) {
   
   
        this.runnable = runnable;
    }

    public DefaultLocalTransactionExecutor(Supplier<R> supplier) {
   
   
        this.supplier = supplier;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值