分布式事务总结

分布式事务

1.基本概念CAP原理 P一定存在,一般追求CP强一致性或者AP高可用。 AP追求高可用,软一致,base原来,软一致性,或者最终一致性。 BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写。是对CAP中AP的一个扩展 CP 强一致性,基于XA协议,事务协调者和事务参与者,有两阶段提交(seata模式) 三阶段提交。无论两阶段还是三阶段都不能完全保证数据一致性。异常都需要人工干预。

两阶段基于数据库的undolog 和redolog日志实现,第一阶段 AP:消息队列的最终一致性。 rocketMq 消息队列的最终一致性,允许短暂超卖。 不需要强一致性的场景,订单-短信服务/订单-物流服务 生产者先发送一个半消息,对消费者不可见,本地事务执行完成后,对消息进行确认,消费者消费消息,会有重试机制。

  1. 半消息发送:消息先发送到MQ,但对消费者不可见。

  2. 本地事务执行:生产者执行本地事务(如创建订单)。

  3. 提交/回滚消息

    • 若事务成功 → MQ将消息标记为可消费。
    • 若事务失败 → MQ删除消息。
  4. 消息投递:仅当事务成功时,消费者才能处理消息。 消费者需要注意幂等性校验,消费者重试机制,重试多次后进入死信队列,人工介入。

`#### 1. 生产者初始化

csharp 复制代码
Java
1public class OrderService {
2    private TransactionMQProducer producer;
3
4    public void init() throws MQClientException {
5        // 创建事务消息生产者
6        producer = new TransactionMQProducer("order_producer_group");
7        producer.setNamesrvAddr("localhost:9876");
8        
9        // 绑定事务监听器(核心事务逻辑入口)
10        producer.setTransactionListener(new OrderTransactionListener(this));
11        
12        // 启动生产者
13        producer.start();
14    }
15}
  • 关键点 :通过 setTransactionListener 绑定事务监听器 OrderTransactionListener,用于后续处理本地事务和状态回查。

2. 发送事务消息(半消息)

java 复制代码
Java
1public void createOrderTransaction(OrderDTO order) throws MQClientException {
2    // 构建消息(Topic、Tag、Key、Body)
3    Message msg = new Message(
4        "order_topic", 
5        "order_tag", 
6        order.getOrderId(),
7        JSON.toJSONBytes(order)
8    );
9    
10    // 发送事务消息(触发半消息机制)
11    TransactionSendResult result = producer.sendMessageInTransaction(msg, order);
12    
13    // 检查事务状态(此处为同步调用结果,非最终消息状态)
14    if (result.getLocalTransactionState() != LocalTransactionState.COMMIT_MESSAGE) {
15        throw new RuntimeException("事务可能已回滚!");
16    }
17}
  • 关键点producer.sendMessageInTransaction(msg, order) 触发以下流程:

    1. 半消息发送 :消息被发送到 RocketMQ Broker,但对消费者不可见(状态为 HALF_MESSAGE)。
    2. 执行本地事务 :自动调用 OrderTransactionListener.executeLocalTransaction()

3. 本地事务执行与消息确认(核心逻辑)

typescript 复制代码
Java
1public class OrderTransactionListener implements TransactionListener {
2    private OrderService orderService;
3
4    @Override
5    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
6        // 解析业务参数(arg 即发送消息时传入的 order 对象)
7        OrderDTO order = (OrderDTO) arg;
8        
9        try {
10            // --------------------------------
11            // 本地事务提交(如订单入库)
12            // --------------------------------
13            boolean success = orderService.createOrder(order);
14            
15            // 根据事务结果返回状态(提交或回滚消息)
16            return success ? LocalTransactionState.COMMIT_MESSAGE 
17                           : LocalTransactionState.ROLLBACK_MESSAGE;
18        } catch (Exception e) {
19            return LocalTransactionState.ROLLBACK_MESSAGE;
20        }
21    }
22
23    @Override
24    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
25        // 事务状态回查(兜底逻辑)
26        String orderId = msg.getKeys();
27        boolean exists = orderService.orderExists(orderId);
28        return exists ? LocalTransactionState.COMMIT_MESSAGE 
29                     : LocalTransactionState.ROLLBACK_MESSAGE;
30    }
31}`
  • 关键点

    • executeLocalTransaction

      • 触发时机 :在 sendMessageInTransaction 发送半消息后立即执行
      • 作用 :执行本地事务(如订单入库),并根据结果决定提交(COMMIT_MESSAGE)或回滚(ROLLBACK_MESSAGE)消息。
    • checkLocalTransaction

      • 触发时机:若生产者崩溃未返回事务状态,RocketMQ 会主动调用此方法回查状态。
      • 作用:检查本地事务是否已提交(如查询订单是否存在),确保最终一致性。

4. RocketMQ Broker 处理消息

根据 LocalTransactionState 的返回值,Broker 执行以下操作:

  • COMMIT_MESSAGE:将半消息标记为可消费状态(对消费者可见)。
  • ROLLBACK_MESSAGE:删除半消息,避免无效投递。
  • UNKNOW:等待下一次回查(默认间隔 1 分钟)

CAP定理,又被叫作布鲁尔定理。对于设计分布式系统来说(不仅仅是分布式事务)的架构师来说,CAP就是你的入门理论。

  • C (一致性):对某个指定的客户端来说,读操作能返回最新的写操作。对于数据分布在不同节点上的数据上来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。
  • A (可用性):非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。合理的时间指的是请求不能无限被阻塞,应该在合理的时间给出返回。合理的响应指的是系统应该明确返回结果并且结果是正确的,这里的正确指的是比如应该返回50,而不是返回40。
  • P (分区容错性):当出现网络分区后,系统能够继续工作。打个比方,这里个集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。

熟悉CAP的人都知道,三者不能共有,如果感兴趣可以搜索CAP的证明,在分布式系统中,网络无法100%可靠,分区其实是一个必然现象,如果我们选择了CA而放弃了P,那么当发生分区现象时,为了保证一致性,这个时候必须拒绝请求,但是A又不允许,所以分布式系统理论上不可能选择CA架构,只能选择CP或者AP架构。

对于CP来说,放弃可用性,追求一致性和分区容错性,我们的zookeeper其实就是追求的强一致。

对于AP来说,放弃一致性(这里说的一致性是强一致性),追求分区容错性和可用性,这是很多分布式系统设计时的选择,后面的BASE也是根据AP来扩展。

相关推荐
xuejianxinokok6 小时前
新版本 python 3.14 性能到底如何?
后端·python
Ray666 小时前
代理模式
后端
考虑考虑6 小时前
Jpa中的枚举类型
spring boot·后端·spring
peter5276 小时前
LangChain4j入门使用
后端
ArabySide6 小时前
【ASP.NET Core】分布式场景下ASP.NET Core中JWT应用教程
分布式·后端·asp.net core
hui函数7 小时前
Python全栈(基础篇)——Day06:后端内容(定义函数+调用函数+实战演示+每日一题)
后端·python
bcbnb7 小时前
Charles隐藏功能全攻略,10个高效技巧让你的抓包调试更专业
后端
用户4099322502127 小时前
PostgreSQL选Join策略有啥小九九?Nested Loop/Merge/Hash谁是它的菜?
后端·ai编程·trae
koddnty7 小时前
协程退出与智能指针
后端·架构