ShardingSphere 分库分表 后的事务
        【摘要】 在 ShardingSphere 中实现分库分表后的分布式事务是一个关键挑战,因为数据被分散到多个数据库实例中,传统的本地事务无法保证跨库操作的原子性。ShardingSphere 提供了多种分布式事务解决方案,适用于不同场景。以下是详细的技术解析和配置指南: 一、ShardingSphere 分布式事务支持ShardingSphere 支持以下三种主流的分布式事务模式:模式适用场景特点XA...
    
    
    
    在 ShardingSphere 中实现分库分表后的分布式事务是一个关键挑战,因为数据被分散到多个数据库实例中,传统的本地事务无法保证跨库操作的原子性。ShardingSphere 提供了多种分布式事务解决方案,适用于不同场景。以下是详细的技术解析和配置指南:
一、ShardingSphere 分布式事务支持
ShardingSphere 支持以下三种主流的分布式事务模式:
| 模式 | 适用场景 | 特点 | 
|---|---|---|
| XA(两阶段提交) | 强一致性要求,如金融交易、订单支付等 | 基于 XA 协议,强一致性但性能较低,依赖数据库的 XA 支持 | 
| SEATA(AT 模式) | 业务复杂度高、需要全局事务的场景(如订单+库存+支付) | 基于 Seata 的 AT 模式,性能较好,但需要引入 Seata 服务端 | 
| SAGA | 长事务、允许最终一致性的场景(如旅游订单、工作流) | 柔性事务,通过补偿机制实现最终一致性,性能高但实现复杂 | 
| 本地事务(TCC) | 适合高并发、短事务的场景(如秒杀系统) | 需要业务代码实现 Try-Confirm-Cancel,灵活性高但开发成本大 | 
二、XA 分布式事务(强一致性)
1. 原理
XA 事务基于 两阶段提交(2PC) 协议,通过事务协调器(TM)和资源管理器(RM)保证跨库事务的原子性。
2. 配置步骤
(1)引入依赖
<!-- Spring Boot + ShardingSphere-JDBC -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.3.2</version>
</dependency>
<!-- 数据库驱动(如 MySQL) -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version>
</dependency>
(2)配置数据源和事务
在 application.yml 中配置分库分表规则和 XA 事务:
spring:
  shardingsphere:
    datasource:
      names: ds0,ds1  # 定义数据源名称
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/db0
        username: root
        password: password
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/db1
        username: root
        password: password
    rules:
      sharding:
        tables:
          t_order:
            actual-data-nodes: ds$->{0..1}.t_order_$->{0..1}  # 分库分表规则
            table-strategy:
              standard:
                sharding-column: order_id
                precise-algorithm-class-name: com.example.OrderTableShardingAlgorithm
            database-strategy:
              standard:
                sharding-column: user_id
                precise-algorithm-class-name: com.example.OrderDatabaseShardingAlgorithm
    props:
      sql-show: true  # 打印 SQL 日志
      # 启用 XA 事务
      transaction-type: XA
      xa-transaction-manager-class-name: org.apache.shardingsphere.transaction.xa.AtomikosXATransactionManager
(3)代码示例
@Service
public class OrderService {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Transactional  // 声明式事务(Spring 管理)
    public void createOrder(Long userId, Long orderId) {
        // 插入订单(跨库操作)
        jdbcTemplate.update("INSERT INTO t_order (order_id, user_id, status) VALUES (?, ?, ?)", 
            orderId, userId, "CREATED");
        
        // 更新库存(假设在另一个库)
        jdbcTemplate.update("UPDATE t_inventory SET stock = stock - 1 WHERE product_id = ?", 
            1001);
    }
}
3. 注意事项
- 性能问题:XA 事务需要全局锁,并发高时可能成为瓶颈。
 - 数据库支持:MySQL 需启用 
binlog_format=ROW(推荐 InnoDB 引擎)。 - 超时设置:调整 
max_actives和max_timeout避免阻塞。 
三、SEATA 分布式事务(AT 模式)
1. 原理
SEATA 的 AT 模式通过 全局锁 和 回滚日志 实现无侵入式的分布式事务,性能优于 XA。
2. 配置步骤
(1)部署 SEATA 服务端
- 下载 SEATA Server。
 - 修改 
file.conf配置存储模式(如file或MySQL)。 - 启动 SEATA Server:
sh seata-server.sh -p 8091 -h 127.0.0.1 
(2)ShardingSphere 集成 SEATA
在 application.yml 中配置:
spring:
  shardingsphere:
    props:
      transaction-type: SEATA
      seata-enable-auto-data-source-proxy: true  # 自动代理数据源
    # 其他分库分表配置...
(3)业务代码改造
- 添加 
@GlobalTransactional注解:@Service public class OrderService { @Autowired private JdbcTemplate jdbcTemplate; @GlobalTransactional // SEATA 全局事务 public void createOrder(Long userId, Long orderId) { jdbcTemplate.update("INSERT INTO t_order (...) VALUES (...)"); jdbcTemplate.update("UPDATE t_inventory SET stock = stock - 1 WHERE ..."); } } - 在 
resources下添加registry.conf(注册中心配置,如 Nacos)。 
3. 注意事项
- 数据源代理:需启用 
seata-enable-auto-data-source-proxy。 - 表结构要求:业务表需有主键,且 SEATA 会创建 
undo_log表。 - 性能优化:调整 SEATA 的 
service.vgroupMapping和store.mode。 
四、SAGA 柔性事务(最终一致性)
1. 原理
SAGA 通过 正向操作 + 补偿操作 实现最终一致性,适用于长事务场景。
2. 配置步骤
(1)定义 SAGA 状态机
编写 JSON 文件(如 order-saga.json):
{
  "Name": "OrderSaga",
  "StartState": "CreateOrder",
  "States": {
    "CreateOrder": {
      "Type": "ServiceTask",
      "ServiceName": "orderService",
      "ServiceMethod": "createOrder",
      "Next": "CompensateOrderOnError"
    },
    "CompensateOrderOnError": {
      "Type": "ServiceTask",
      "ServiceName": "orderService",
      "ServiceMethod": "compensateOrder",
      "IsCompensation": true
    }
  }
}
(2)集成 ShardingSphere
在 application.yml 中配置:
spring:
  shardingsphere:
    props:
      transaction-type: SAGA
      saga-state-machine-path: classpath:order-saga.json
3. 适用场景
- 订单超时取消
 - 旅游套餐预订(涉及酒店、机票、保险等多个服务)
 
五、本地事务(TCC)
1. 原理
TCC(Try-Confirm-Cancel)通过业务代码实现两阶段提交:
- Try:预留资源(如冻结库存)。
 - Confirm:确认操作(如实际扣减库存)。
 - Cancel:回滚操作(如释放冻结库存)。
 
2. 代码示例
public interface TccOrderService {
    @Transactional
    boolean tryOrder(Long orderId);  // 预留资源
    @Transactional
    boolean confirmOrder(Long orderId);  // 确认提交
    @Transactional
    boolean cancelOrder(Long orderId);  // 回滚
}
3. 适用场景
- 秒杀系统(高并发、短事务)
 - 支付系统(需要精确控制资源)
 
六、性能对比与选型建议
| 模式 | 一致性 | 性能 | 实现复杂度 | 适用场景 | 
|---|---|---|---|---|
| XA | 强一致 | 低 | 低 | 金融交易 | 
| SEATA | 强一致 | 中 | 中 | 订单+库存+支付 | 
| SAGA | 最终一致 | 高 | 高 | 旅游订单、工作流 | 
| TCC | 最终一致 | 极高 | 极高 | 秒杀、高并发支付 | 
推荐选型:
- 优先 SEATA:平衡一致性与性能,适合大多数业务。
 - 高并发场景选 TCC:如秒杀系统。
 - 长事务选 SAGA:如旅游订单。
 
七、常见问题与排查
1. XA 事务超时
- 原因:网络延迟或数据库锁等待。
 - 解决:调整 
max_actives和max_timeout:spring: shardingsphere: props: xa-transaction-manager-class-name: org.apache.shardingsphere.transaction.xa.AtomikosXATransactionManager max-actives: 200 max-timeout: 300000 # 5分钟 
 2. SEATA 报错 No available service
- 原因:SEATA Server 未注册或网络不通。
 - 解决:
- 检查 SEATA Server 日志。
 - 确认 
registry.conf配置正确(如 Nacos 地址)。 
 
3. 分库分表后事务不生效
- 原因:未正确配置 
transaction-type。 - 解决:检查 
application.yml是否包含:spring: shardingsphere: props: transaction-type: XA # 或 SEATA/SAGA 
八、总结
- XA:简单但性能低,适合强一致性场景。
 - SEATA:平衡性能与一致性,推荐作为首选方案。
 - SAGA/TCC:适合柔性事务或高并发场景,但实现复杂。
 
通过合理选择事务模式,可以确保 ShardingSphere 分库分表后的数据一致性,同时兼顾系统性能。
            【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
                cloudbbs@huaweicloud.com
                
            
        
        
        
        
        - 点赞
 - 收藏
 - 关注作者
 
            
           
评论(0)