分布式事务——纯MQ实现

本文介绍了使用MQ实现分布式事务的原理和一个具体的场景实践,包括支付宝转账到余额宝的例子。通过生产者发送消息的可靠性检查、消费者的幂等性和异常重试机制,确保事务的一致性。在实践中,涉及了队列创建、Maven依赖、配置添加以及支付宝和余额宝两端的代码编写和测试。

一、MQ实现分布式事务,最简单的原理框架:
借助MQ的消息可靠传递,实现业务间解耦、事务强一致

1、>> 生产者发送消息做可靠性检查,确保消息真正投递出去;

2、>> 消费者做幂等,确保业务没有重复执行;

3、>> 消费者做异常重试,反复出错时需要捕捉异常并记录,以便手工干预;

二、场景实践:
场景
以支付宝转账到余额宝为例,在支付宝已经扣款成功的情况下,余额宝一定收到转账

>> 支付宝和余额宝是两个微服务;

>> 用户用支付宝转1万元到余额宝;

支付宝账户先扣除金额,MQ通知余额宝账户添加金额;

>> 支付宝账户表: update A set amount = amount - 10000 where userId = 1;

>> 余额宝账户表: update B set amount = amount + 10000 where userId = 1;

具体操作
1、创建队列
>> 创建一个持久化的队列,名称为money;

Durable(持久化保存),Transient(即时保存)。

2、 maven引入
(余额宝和支付宝两个服务都需要)

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
7
<dependency>
 
    <groupId>org.springframework.boot</groupId>
 
    <artifactId>spring-boot-starter-amqp</artifactId>
 
</dependency>



AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。



3、  添加配置
(余额宝和支付宝两个服务都需要)

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
spring:   
 
    rabbitmq:
 
        host: 192.168.222.26 #MQ地址
 
        port: 5672 #MQ端口
 
        username: admin #MQ用户名
 
        password: admin #MQ密码
 
        publisher-confirms: true #开启消息发送成功监听
 
        publisher-returns: true #开启消息发送失败监听
 
        listener:
 
            simple:
 
                acknowledge-mode: manual #手动提交事务



4 支付宝端代码编写
向支付宝账号扣款,同时发消息到队列中,通知余额宝账号金额更新

>>  配置MQ发送过程监听

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package cn.my.server.clientdemo.zhifu;
  
import javax.annotation.PostConstruct;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ReturnCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
  
/**
 * 配置MQ发送过程监听
 * @author twotiger-wxm.
 * @date 2020-3-3.
 */
@Configuration
public class RabbmitMqConfig {
  
        @Autowired
        private RabbitTemplate rabbitTemplate;
  
        @PostConstruct
        public void init() {
            // 设置发送成功回调
            rabbitTemplate.setConfirmCallback(initConfirmCallback());
            // 设置发送失败回调
            rabbitTemplate.setReturnCallback(initReturnCallback());
        }
  
        @Bean
        public ReturnCallback initReturnCallback(){
            return new FailedListener();
        }
  
        @Bean
        public ConfirmCallback initConfirmCallback(){
            return new SuccessListener();
        }
  
}

 

[AppleScript] 纯文本查看 复制代码
?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
### MQ分布式事务实现方案 在分布式系统中,消息队列(MQ)作为异步通信的核心组件,在解决分布式事务问题方面扮演着重要角色。以下是几种常见的基于MQ分布式事务解决方案及其技术细节: #### 1. RocketMQ事务消息 RocketMQ提供了原生支持的事务消息功能,允许生产者发送半消息(Half Message),只有当本地事务执行完成后才会确认该消息并将其投递给消费者[^1]。 - **工作流程**:生产者发送一条半消息到Broker;随后,生产者的业务逻辑完成后再向Broker发送Commit或Rollback指令。 - **优点**:能够保证强一致性和高可靠性。 - **缺点**:依赖于特定的消息中间件特性。 ```java // RocketMQ事务消息示例代码 public class TransactionProducer { public static void main(String[] args) throws Exception { TransactionMQProducer producer = new TransactionMQProducer("transaction_producer_group"); producer.setNamesrvAddr("localhost:9876"); producer.start(); String destination = "TopicTest"; Message msg = new Message(destination, ("Hello RocketMQ").getBytes(RemotingHelper.DEFAULT_CHARSET)); SendResult sendResult = producer.sendMessageInTransaction(msg, null); System.out.printf("%s%n", sendResult); producer.shutdown(); } } ``` --- #### 2. 最大努力通知机制 最大努力通知是一种弱一致性保障方式,适用于对实时性要求不高的场景。它通过不断重试来尝试确保消息被消费方接收到[^1]。 - **工作流程**:生产者将消息发送至MQ后,定期轮询目标系统的状态反馈表,直到确认对方已接收消息为止。 - **优点**:简单易用,无需复杂的协调器参与。 - **缺点**:无法完全杜绝丢失风险,可能带来重复处理的风险。 --- #### 3. 可靠消息最终一致性模式 此方法利用数据库存储消息记录,并结合定时任务检查未完成的任务状态,从而达到全局的一致性效果[^2]。 - **工作流程**: 1. 生产者先将待发消息存入本地数据库; 2. 成功入库后再推送至MQ; 3. 如果推送失败,则启动补偿机制重新尝试直至成功。 - **优点**:兼容性强,可适配多种主流MQ产品。 - **缺点**:增加了额外的数据持久化开销。 --- #### 4. TCC模式下的分布式事务管理 TCC(Try-Confirm-Cancel)是一种柔性事务框架,特别适合复杂业务场景下的跨服务协作需求[^3]。 - **核心思想**:分为三个阶段——预占资源(Try)、正式提交(Confirm)以及取消操作(Cancel)。每个环节都需要明确定义对应的接口行为。 - **适用范围**:金融支付、库存扣减等领域尤为常见。 ```python # Python伪代码展示TCC模式 class PaymentService: def try_payment(self, order_id): """ 预占资金 """ pass def confirm_payment(self, order_id): """ 正式扣除金额 """ pass def cancel_payment(self, order_id): """ 解冻冻结的资金 """ pass ``` --- #### 5. RabbitMQ与死信队列配合使用 对于某些特殊场景,可以借助RabbitMQ内置的DLX(Dead Letter Exchange)功能构建可靠的错误恢复路径[^4]。一旦正常队列中的消息因多次交付失败而失效时,它们会被自动路由到指定的目标地址供后续分析处理。 --- ### 总结 以上列举了几种典型的基于MQ分布式事务设计方案,开发者应根据具体的项目背景和技术栈特点灵活选用合适的策略组合。无论是追求高性能还是极致准确性,这些工具都能提供相应的支撑能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值