Seata 2PC是如何支持的?谈谈你的理解?

1 个回答

  • 梅拾璎
    希望有人告诉你开心比对错更重要。
    Seata 是一款开源分布式事务框架,通过 **两阶段提交协议(2PC)** 来实现分布式事务的强一致性,尤其在其 **AT 模式** 下,优化了传统 2PC 的性能和使用便捷性。 ### **1. 什么是两阶段提交协议(2PC)** 两阶段提交分为两个阶段,分别负责事务的准备和提交/回滚: 1. **准备阶段(Prepare Phase)** - **事务管理器(TM)** 向各参与者(资源管理器 RM)发送准备请求。 - **资源管理器(RM)** 执行业务逻辑,但不提交本地事务,只保存操作快照(undo_log)并锁定资源。 2. **提交阶段(Commit Phase)** - 若所有参与者准备成功,TM 通知各 RM 提交事务,释放资源。 - 若任一参与者失败,TM 通知所有 RM 回滚操作,恢复数据到初始状态。 ### **2. Seata 2PC 的实现原理** 在 AT 模式下,Seata 优化了传统 2PC 的机制,通过数据库快照和日志管理实现高效的事务管理: #### **1)准备阶段** - **拦截 SQL 操作:** Seata 的 `DataSourceProxy` 拦截所有业务 SQL 语句,解析 SQL 和业务数据,记录操作前后的数据快照。 - **本地事务提交:** 在准备阶段,Seata 的 RM 会提交本地事务并释放资源锁,但保留快照(undo_log),以便回滚时使用。 #### **2)提交阶段** - **事务提交:** 当全局事务提交时,TM 通知各 RM 删除对应的快照(undo_log),事务完成。 - **事务回滚:** 当全局事务回滚时,各 RM 根据 `undo_log` 快照生成反向 SQL,撤销之前的操作,恢复数据到初始状态。 ### **3. 核心组件和工作机制** Seata 的 2PC 实现依赖以下核心组件: | **组件** | **功能** | |-------------------|---------------------------------------------------------------------------------------------| | **事务管理器(TM)** | 全局事务的发起者和协调者,负责开启、提交或回滚分布式事务。 | | **资源管理器(RM)** | 执行分支事务的业务逻辑,记录数据快照,并响应 TM 的提交或回滚请求。 | | **事务协调器(TC)** | 全局事务的中央协调者,维护事务状态,管理参与者信息,协调事务提交或回滚。 | #### **undo_log 表** - 用于存储业务操作的快照数据。 - 每个业务数据库中需创建该表,供 Seata 自动记录和清理。 - 表结构示例: ```sql CREATE TABLE undo_log ( id BIGINT(20) NOT NULL AUTO_INCREMENT, branch_id BIGINT(20) NOT NULL, xid VARCHAR(128) NOT NULL, context VARCHAR(128) NOT NULL, rollback_info LONGBLOB NOT NULL, log_status INT(11) NOT NULL, log_created DATETIME NOT NULL, log_modified DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY ux_undo_log (xid, branch_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` ### **4. 开发与部署步骤** 1. **引入依赖** 在项目中引入 Seata 的 Maven 依赖: ```xml <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>最新版本号</version> </dependency> ``` 2. **部署 Seata Server** 下载并部署 Seata Server,确保其能与注册中心(如 Nacos、Zookeeper)和配置中心通信。 3. **配置 Seata** 配置业务服务连接 Seata: ```yaml seata: enabled: true application-id: your-application-name tx-service-group: my_tx_group service: vgroup-mapping.my_tx_group: default group-list: "127.0.0.1:8091" ``` 4. **创建 undo_log 表** 在每个业务库中执行建表脚本,确保支持事务回滚。 5. **数据源代理** 配置代理数据源以支持事务日志管理: ```java @Bean public DataSource dataSource() { return new DataSourceProxy(originalDataSource()); } ``` 6. **标注分布式事务** 使用 `@GlobalTransactional` 注解标记分布式事务方法: ```java @GlobalTransactional(name = "create_order_tx", rollbackFor = Exception.class) public void createOrder(Order order) { productService.deductStock(order.getProductId(), order.getQuantity()); paymentService.makePayment(order.getUserId(), order.getTotalPrice()); saveOrder(order); } ``` ### **5. Seata 2PC 的优势** 1. **高性能:** - 提前提交本地事务并释放资源锁,减少锁占用时间。 2. **零侵入:** - 无需修改业务逻辑,支持透明的分布式事务管理。 3. **自动清理:** - 提交事务后,自动清理 `undo_log`,保持数据库整洁。 ### **6. 注意事项** 1. **`undo_log` 表与业务库共存:** - Seata 不需要单独的数据库,`undo_log` 表直接存储在业务库中。 2. **事务隔离性:** - 可能因第一阶段本地事务提交带来脏读风险,建议使用 `FOR UPDATE` 等方式提升隔离性。 3. **数据库支持:** - 目前 Seata 支持 MySQL、PostgreSQL、Oracle 等主流数据库。 通过以上支持机制,Seata 在分布式事务场景下实现了可靠的两阶段提交,同时降低了传统 2PC 的复杂性和性能成本。
    发布于 2024-11-23 03:06 •IP属地 重庆
    举报
    评论
    收藏