Alibaba Spring Cloud 六 Seata 的核心组件:RM

Alibaba Spring Cloud Seata 中,Resource Manager (RM) 是三大核心组件之一。它主要负责管理分支事务中的资源(如数据库、文件等),并与 Transaction Coordinator (TC) 协作完成分支事务的注册、提交和回滚。RM 是分布式事务实际操作的执行者,保证本地事务与全局事务的协调一致。


1. RM 的核心功能

  1. 分支事务的注册:

    • 在本地事务执行前,RM 向 TC 注册分支事务。
    • RM 将分支事务绑定到全局事务(通过 XID 关联)。
  2. 分支事务的执行:

    • RM 在本地事务中执行具体的业务逻辑(如数据库操作)。
  3. 分支事务状态的报告:

    • RM 在本地事务完成后,向 TC 汇报分支事务的执行状态(成功或失败)。
  4. 事务提交或回滚:

    • 根据 TC 的指令,RM 提交或回滚分支事务。
    • AT 模式 中,RM 会通过 Undo Log(回滚日志)恢复数据状态。

2. RM 的工作原理

RM 是嵌入在业务服务中的组件,用于处理资源操作的事务管理。以下是 RM 的主要工作流程:

2.1 分支事务注册

  • 在分支事务执行之前,RM 向 TC 发起注册请求。
  • TC 返回分支事务 ID,并将其记录在全局事务中。

2.2 分支事务执行

  • RM 执行具体的资源操作,例如:
    • 数据库的插入、更新操作。
    • 消息队列的发送。
  • AT 模式 中,RM 还会记录 Undo Log(回滚日志)。

2.3 状态报告

  • 分支事务执行完成后,RM 向 TC 报告执行结果(成功或失败)。

2.4 提交或回滚

  • 如果 TC 决定提交事务,RM 提交本地事务。
  • 如果 TC 决定回滚事务,RM 根据 Undo Log 恢复本地事务的初始状态。

3. RM 在不同模式下的表现

3.1 AT 模式

  • 在 AT 模式中,RM 使用 JDBC 拦截器记录 Undo Log,管理数据库事务。
  • Undo Log 记录每次更新前的数据快照,用于回滚时恢复原始状态。
执行过程:
  1. 本地事务执行时,生成 Undo Log。
  2. TC 指定提交时,清除 Undo Log。
  3. TC 指定回滚时,读取 Undo Log 恢复原始数据。

3.2 TCC 模式

  • 在 TCC 模式中,RM 手动实现分支事务的三阶段逻辑:
    1. Try:预留资源。
    2. Confirm:正式提交资源。
    3. Cancel:释放预留资源。
执行过程:
  1. Try 阶段执行预留逻辑,例如冻结库存或资金。
  2. TC 指定提交时,调用 Confirm 方法。
  3. TC 指定回滚时,调用 Cancel 方法。

3.3 SAGA 模式

  • RM 执行业务的前向操作和补偿操作。
  • 每个分支事务需要实现补偿逻辑。

4. RM 的实现与使用

4.1 配置 RM

RM 是嵌入在业务服务中的组件,通过 Spring Boot 配置实现。

引入依赖

在业务服务的 pom.xml 中添加 Seata 的依赖:

xml 复制代码
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.6.1</version>
</dependency>
配置数据源代理

application.yml 中配置 Seata 的数据源代理:

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

  seata:
    enabled: true
    tx-service-group: my_tx_group

Seata 会自动代理数据源,拦截事务操作并记录 Undo Log。


4.2 使用 RM 管理分支事务

以下示例展示了一个扣减库存的分支事务:

java 复制代码
@Service
public class InventoryService {

    @Autowired
    private InventoryRepository inventoryRepository;

    // 分支事务:扣减库存
    public void deductStock(Long productId, int quantity) {
        Inventory inventory = inventoryRepository.findById(productId)
                .orElseThrow(() -> new RuntimeException("商品不存在"));
        
        if (inventory.getAvailableStock() < quantity) {
            throw new RuntimeException("库存不足");
        }

        // 扣减库存
        inventory.setAvailableStock(inventory.getAvailableStock() - quantity);
        inventoryRepository.save(inventory);
    }
}

4.3 AT 模式下的 Undo Log

Undo Log 表结构

在数据库中创建 Undo Log 表,用于记录回滚日志:

sql 复制代码
CREATE TABLE undo_log (
    id BIGINT AUTO_INCREMENT,
    branch_id BIGINT NOT NULL,
    xid VARCHAR(128) NOT NULL,
    context VARCHAR(128) NOT NULL,
    rollback_info LONGBLOB NOT NULL,
    log_status INT NOT NULL,
    log_created TIMESTAMP NOT NULL,
    log_modified TIMESTAMP NOT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY (xid, branch_id)
);
Undo Log 的生成与使用
  • 生成: 在每次本地事务执行时,Seata 自动生成 Undo Log。
  • 使用: 在回滚时,Seata 读取 Undo Log 恢复数据。

5. RM 的配置项

以下是 RM 的常用配置项:

seata.client.rm.async.commit.buffer.limit

  • 异步提交的缓冲区大小。
  • 默认值:10000。

seata.client.rm.lock.retry.interval

  • 获取分布式锁时的重试间隔(毫秒)。
  • 默认值:10。

seata.client.rm.lock.retry.times

  • 获取分布式锁的最大重试次数。
  • 默认值:30。

6. RM 的运行与调试

检查事务锁

在分布式事务执行时,RM 会为操作的资源添加分布式锁,锁信息存储在 lock_table 中。

锁表结构
sql 复制代码
CREATE TABLE lock_table (
    row_key VARCHAR(128) NOT NULL,
    xid VARCHAR(128) NOT NULL,
    transaction_id BIGINT,
    branch_id BIGINT,
    resource_id VARCHAR(256),
    gmt_create TIMESTAMP,
    gmt_modified TIMESTAMP,
    PRIMARY KEY (row_key)
);

检查 Undo Log

当事务需要回滚时,RM 会读取 undo_log 表并恢复数据。


7. RM 的性能优化与注意事项

  1. Undo Log 清理:

    • 定期清理历史 Undo Log,避免表数据膨胀。
    • Seata 提供了自动清理工具。
  2. 分布式锁性能:

    • 优化 lock_table 的索引,提升锁的获取效率。
    • 在高并发场景下,尽量缩小事务粒度,减少锁冲突。
  3. 事务粒度控制:

    • 避免在一个事务中操作过多的资源,防止事务冲突。
  4. 事务超时配置:

    • 配置合理的事务超时时间,避免长时间锁定资源。

8. 总结

Resource Manager (RM) 是 Seata 框架中管理分支事务的关键组件,负责资源的实际操作和事务的提交与回滚。在开发中:

  • RM 的行为由具体的事务模型(AT、TCC 等)决定。
  • 在 AT 模式下,RM 依赖 Undo Log 来支持事务的回滚。
相关推荐
island13141 小时前
【QT】 控件 -- 显示类
开发语言·数据库·qt
Andya_net1 小时前
网络安全 | F5-Attack Signatures-Set详解
网络·数据库·web安全
码农幻想梦2 小时前
实验二 数据库的附加/分离、导入/导出与备份/还原
数据库·oracle
hillstream33 小时前
Synology 群辉NAS安装(6)安装mssql
数据库·sqlserver
bing_1583 小时前
Redis 的缓存穿透、缓存击穿和缓存雪崩是什么?如何解决?
redis·spring·缓存
行十万里人生3 小时前
Qt 控件与布局管理
数据库·qt·microsoft·华为od·华为·华为云·harmonyos
betazhou4 小时前
sysbench压力测试工具mysql以及postgresql
数据库·mysql·postgresql
莳花微语4 小时前
OGG 19C 集成模式启用DDL复制
数据库·oracle
花心蝴蝶.4 小时前
Spring MVC 综合案例
java·后端·spring
潜水的码不二4 小时前
Redis高阶3-缓存双写一致性
数据库·redis·缓存