亿级分布式系统架构演进实战(十)- 垂直拆分(分布式事务管理设计)

亿级分布式系统架构演进实战(一)- 总体概要
亿级分布式系统架构演进实战(二)- 横向扩展(服务无状态化)
亿级分布式系统架构演进实战(三)- 横向扩展(数据库读写分离)
亿级分布式系统架构演进实战(四)- 横向扩展(负载均衡与弹性伸缩)
亿级分布式系统架构演进实战(五)- 横向扩展(缓存策略设计)
亿级分布式系统架构演进实战(六)- 横向扩展(监控与日志体系)
亿级分布式系统架构演进实战(七)- 横向扩展(安全防护设计)
亿级分布式系统架构演进实战(八)- 垂直拆分(领域划分及垂直分库设计)
亿级分布式系统架构演进实战(九)- 垂直拆分(服务间通信设计)

一、核心目标

解决跨服务数据一致性问题,平衡性能与一致性

  1. 强一致性:确保跨服务操作原子性,适用于金融等高敏感场景。
  2. 最终一致性:通过异步补偿机制,提升系统吞吐量和可用性。
  3. 可观测性:全链路监控事务状态,支持人工介入异常处理。

二、强一致性方案

1. Seata AT模式(自动补偿)

设计意图

简化开发 :通过全局锁机制自动回滚事务,减少业务侵入。

适用场景:电商订单创建(扣库存+生成订单)。

技术实现

全局事务ID(XID) :Seata客户端生成唯一ID,贯穿所有子事务。

数据快照:记录事务前后的数据镜像,用于自动回滚。

生产配置示例

yaml 复制代码
# Seata Server配置(Nacos注册中心)
seata:
  registry:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848

优劣势

优势 :开发简单,适合传统事务迁移场景。

劣势:全局锁可能导致性能瓶颈(建议分库分表优化)。


2. XA两阶段提交(数据库原生支持)

设计意图

强一致性保障:数据库原生支持,适合金融转账等高敏感场景。

技术实现

Phase 1(Prepare) :所有参与者锁定资源,返回准备状态。

Phase 2(Commit/Rollback):协调者根据Prepare结果提交或回滚。

代码示例

java 复制代码
// MySQL XA事务示例
XADataSource xaDataSource = ... // 获取XA数据源
XAResource xaRes = xaDataSource.getXAConnection().getXAResource();
Xid xid = new MyXid(); // 全局事务ID

try {
    xaRes.start(xid, XAResource.TMNOFLAGS);
    // 执行SQL操作(如扣款)
    xaRes.end(xid, XAResource.TMSUCCESS);
    xaRes.prepare(xid);
    xaRes.commit(xid, false); // 提交事务
} catch (XAException e) {
    xaRes.rollback(xid); // 回滚事务
}

优劣势

优势 :严格ACID,适合银行核心系统。

劣势:同步阻塞,性能较低(TPS < 500)。


3. TCC模式(手动补偿)

设计意图

灵活控制:通过Try-Confirm-Cancel三阶段,支持自定义补偿逻辑。

技术实现

Try :预留资源(如冻结库存)。

Confirm :提交事务(如确认扣减库存)。

Cancel:回滚预留(如解冻库存)。

代码示例

java 复制代码
public interface InventoryTccService {
    @TwoPhaseBusinessAction(name = "prepare", commitMethod = "confirm", rollbackMethod = "cancel")
    boolean prepare(BusinessActionContext context, @BusinessActionContextParameter(paramName = "skuId") String skuId, int count);
    
    boolean confirm(BusinessActionContext context);
    boolean cancel(BusinessActionContext context);
}

生产配置

幂等性保障 :通过唯一事务ID避免重复提交。

超时控制:设置Try阶段最长等待时间(如30秒)。

优劣势

优势 :高性能,适合秒杀等高并发场景。

劣势:开发复杂,需手动实现补偿逻辑。


三、最终一致性方案

1. Saga模式(正向+逆向补偿)

设计意图

长事务处理:通过事件驱动逐步执行事务,失败时逆向补偿。

技术实现

正向操作 :依次执行子事务(如创建订单 → 扣库存)。

补偿操作:逆向回滚(如取消订单 → 返还库存)。

代码示例

java 复制代码
// Saga流程定义(使用Apache Camel)
from("direct:createOrder")
    .saga()
    .compensation("direct:cancelOrder")
    .to("bean:orderService?method=createOrder")
    .to("bean:inventoryService?method=deductStock");

from("direct:cancelOrder")
    .to("bean:orderService?method=cancelOrder")
    .to("bean:inventoryService?method=restoreStock");

优劣势

优势 :支持复杂业务流程,适合电商订单。

劣势:补偿逻辑需覆盖所有失败场景。


2. 异步校对(定时补偿)

设计意图

数据最终一致:通过定时任务检测并修复不一致状态。

技术实现

定时任务 :扫描事务表,检查未完成的事务。

补偿触发:对异常事务执行修复(如重试或回滚)。

生产配置示例

sql 复制代码
-- 检测未完成订单
SELECT order_id 
FROM orders 
WHERE status = 'CREATED' 
  AND create_time < NOW() - INTERVAL '10 minutes';

优劣势

优势 :实现简单,适合对一致性要求不高的场景(如日志记录)。

劣势:修复延迟,可能影响用户体验。


3. 事务消息(RocketMQ)

设计意图

可靠消息投递:确保本地事务与消息发送的原子性。

技术实现

半消息 :消息暂存Broker,不可被消费。

事务状态回查:Broker定期检查生产者事务状态。

代码示例

java 复制代码
// 发送事务消息
TransactionSendResult result = producer.sendMessageInTransaction(message, order);
if (result.getLocalTransactionState() == LocalTransactionState.ROLLBACK_MESSAGE) {
    // 事务回滚处理
}

// 消费端幂等处理
if (redis.setnx(orderId, "PROCESSING") == 1) {
    inventoryService.deductStock(orderId);
}

优劣势

优势 :高吞吐量(TPS > 10k),适合订单创建场景。

劣势:依赖消息队列可用性。


4. 本地事务消息表

设计意图

去中心化事务:通过本地事务保证业务操作与消息写入的原子性。

技术实现

  1. 业务表与消息表在同一个事务中写入。
  2. 定时任务扫描消息表,发送消息到MQ。

数据库表设计

sql 复制代码
CREATE TABLE transaction_messages (
    id BIGINT PRIMARY KEY,
    topic VARCHAR(100),
    payload TEXT,
    status ENUM('PENDING', 'SENT'),
    created_time TIMESTAMP
);

优劣势

优势 :不依赖MQ事务消息功能,兼容性高。

劣势:需额外维护消息表,增加数据库压力。


5. Transactional Outbox

设计意图

可靠事件发布:通过数据库事务确保事件持久化,外部消费者轮询获取。

技术实现

  1. 业务操作与事件写入同一事务。
  2. 独立进程轮询事件表,发布到MQ。

代码示例

java 复制代码
// 发布事件
@Transactional
public void createOrder(Order order) {
    orderRepository.save(order);
    outboxRepository.save(new OutboxEvent("order_created", order.getId()));
}

优劣势

优势 :解耦业务与消息发送,适合微服务架构。

劣势:增加轮询开销,可能引入延迟。


四、事务生命周期与监控

1. 事务状态记录

唯一事务ID :全局唯一标识符(如UUID)。

状态跟踪:记录事务的开始、提交、回滚状态。

数据库表设计

sql 复制代码
CREATE TABLE transaction_logs (
    tx_id VARCHAR(36) PRIMARY KEY,
    service_name VARCHAR(50),
    status ENUM('STARTED', 'COMMITTED', 'ROLLBACKED'),
    created_time TIMESTAMP,
    updated_time TIMESTAMP
);

2. 监控与告警

核心指标

事务成功率 :统计各服务事务成功/失败比例。

延迟分布:P50、P90、P99事务处理时间。

告警规则

yaml 复制代码
# Prometheus告警配置
groups:
- name: transaction-alerts
  rules:
  - alert: HighTransactionFailureRate
    expr: sum(rate(transaction_failed_total[5m])) / sum(rate(transaction_total[5m])) > 0.05
    labels:
      severity: critical
    annotations:
      summary: "事务失败率超过5% (当前值: {{ $value }})"

人工介入流程

  1. 异常标记:监控系统标记状态为"待处理"的事务。
  2. 人工处理:通过管理后台查看详情,触发补偿或通知开发。

五、方案对比与选型建议

方案 一致性 性能 复杂度 适用场景
Seata AT 传统业务迁移
XA两阶段提交 金融转账
TCC 高并发秒杀
Saga 最终 长流程事务(电商订单)
事务消息 最终 异步通知场景
Transactional Outbox 最终 微服务解耦
相关推荐
Ramos丶3 分钟前
【ABAP】 从无到有 新建一个Webdynpro程序
java·前端·javascript
一路向北North12 分钟前
使用reactor-rabbitmq库监听Rabbitmq
分布式·rabbitmq·ruby
sniper_fandc14 分钟前
SpringMVC详解
java·springmvc
TT哇1 小时前
【Java EE初阶】计算机是如何⼯作的
java·redis·java-ee
zkmall2 小时前
企业电商解决方案哪家好?ZKmall模块商城全渠道支持 + 定制化服务更省心
大数据·运维·重构·架构·开源
美狐美颜sdk6 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
Amy187021118236 小时前
赋能低压分布式光伏“四可”建设,筑牢电网安全新防线
分布式
小雷FansUnion8 小时前
深入理解MCP架构:智能服务编排、上下文管理与动态路由实战
人工智能·架构·大模型·mcp
Fireworkitte8 小时前
Apache POI 详解 - Java 操作 Excel/Word/PPT
java·apache·excel
weixin-a153003083168 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html