Seata 的 TCC(Try-Confirm-Cancel)模式是一种用于实现分布式事务的补偿机制。TCC 模式适用于那些无法直接使用 Seata 的 AT 模式的情况,比如当涉及到非 SQL 数据源时。下面我们将通过一个简单的示例来介绍如何在 Seata 中使用 TCC 模式。
TCC 模式概述
TCC 模式包括三个阶段:
- Try:尝试阶段,进行业务检查,并预留必须的业务资源。
- Confirm:确认阶段,完成业务操作。
- Cancel:取消阶段,释放 Try 阶段预留的业务资源。
准备工作
-
安装 Seata Server:
- 按照之前的指南安装并启动 Seata Server。
-
配置 Nacos:
- 如果还没有配置 Nacos,参照之前的指南完成 Nacos 的安装和配置。
-
创建 Spring Boot 项目:
- 创建一个新的 Spring Boot 项目,并添加必要的依赖。
<dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata-tcc</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.3.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
- 创建一个新的 Spring Boot 项目,并添加必要的依赖。
-
配置 Seata Client:
- 在
application.yml
文件中配置 Seata Client。spring: cloud: alibaba: seata: tx-service-group: tcc_tx_group enable-auto-data-source-proxy: false service: vgroup-mapping: tcc_tx_group: default enable-degrade: false disable-global-transaction: false client: rm: report-success-enable: true lock: retry-interval: 10 retry-times: 30 retry-policy-branch-rollback-on-conflict: true tm: default-global-transaction-timeout: 60000 seata: enabled: true config: type: nacos nacos: server-addr: 127.0.0.1:8848 group: SEATA_GROUP namespace: username: password:
- 在
实现 TCC 服务
-
创建 TCC 服务接口:
- 创建一个 TCC 服务接口,定义 Try、Confirm 和 Cancel 方法。
public interface TransferService { /** * Try stage. * @param fromAccount 转出账户 * @param toAccount 转入账户 * @param amount 转账金额 * @return 返回是否成功 */ boolean tryTransfer(String fromAccount, String toAccount, int amount); /** * Confirm stage. * @param fromAccount 转出账户 * @param toAccount 转入账户 * @param amount 转账金额 * @return 返回是否成功 */ boolean confirmTransfer(String fromAccount, String toAccount, int amount); /** * Cancel stage. * @param fromAccount 转出账户 * @param toAccount 转入账户 * @param amount 转账金额 * @return 返回是否成功 */ boolean cancelTransfer(String fromAccount, String toAccount, int amount); }
- 创建一个 TCC 服务接口,定义 Try、Confirm 和 Cancel 方法。
-
实现 TCC 服务:
- 创建一个 TCC 服务实现类。
@Service public class TransferServiceImpl implements TransferService { @Override public boolean tryTransfer(String fromAccount, String toAccount, int amount) { // 进行业务检查,预留资源 // ... return true; } @Override public boolean confirmTransfer(String fromAccount, String toAccount, int amount) { // 完成业务操作 // ... return true; } @Override public boolean cancelTransfer(String fromAccount, String toAccount, int amount) { // 释放预留资源 // ... return true; } }
- 创建一个 TCC 服务实现类。
-
创建 TCC 事务管理器:
- 创建一个 TCC 事务管理器,用于管理 TCC 事务。
@Component public class TccTransactionManager { @Autowired private TransferService transferService; @GlobalTransactional(name = "transfer-tcc", rollbackFor = Exception.class) public void transfer(String fromAccount, String toAccount, int amount) { // 开启 TCC 事务 boolean tryResult = transferService.tryTransfer(fromAccount, toAccount, amount); if (!tryResult) { throw new IllegalStateException("Try transfer failed"); } } }
- 创建一个 TCC 事务管理器,用于管理 TCC 事务。
-
创建 REST 控制器:
- 创建 REST 控制器来暴露转账接口。
@RestController public class TransferController { @Autowired private TccTransactionManager tccTransactionManager; @PostMapping("/tcc-transfer") public String transfer(@RequestParam("from") String fromAccount, @RequestParam("to") String toAccount, @RequestParam("amount") int amount) { tccTransactionManager.transfer(fromAccount, toAccount, amount); return "Transfer successful"; } }
- 创建 REST 控制器来暴露转账接口。
测试 TCC 事务
-
启动 Nacos 和 Seata 服务:
- 确保 Nacos 和 Seata 服务正在运行。
-
运行 Spring Boot 应用:
- 运行
Application.java
类启动 Spring Boot 应用程序。
- 运行
-
执行测试:
- 使用 Postman 或者浏览器访问相应的端点,触发 TCC 事务。
- URL:
http://localhost:8080/tcc-transfer?from=Alice&to=Bob&amount=100
- URL:
- 使用 Postman 或者浏览器访问相应的端点,触发 TCC 事务。
注意事项
- TCC 事务的参与者:TCC 事务需要显式地参与事务,即在服务实现中明确调用 Try、Confirm 和 Cancel 方法。
- 异常处理:在 Try 阶段发生异常会导致事务回滚。在 Confirm 或 Cancel 阶段发生异常,Seata 会尝试重试直至成功。
- 资源预留:在 Try 阶段,需要预留必要的资源,例如冻结账户余额、锁定库存等。
- 资源释放:在 Cancel 阶段,需要释放 Try 阶段预留的资源。
通过这个示例,你可以了解到如何在 Seata 中使用 TCC 模式来实现分布式事务。TCC 模式适用于那些无法使用 AT 模式的场景,尤其是涉及非 SQL 数据源的情况。如果你需要更详细的配置指南或遇到具体问题,请随时告诉我。