一、环境准备
1、环境搭建,查看Spring Cloud专栏
2、seate-server运行成功,参考文章:【Seata、Nacos】Win安装Seata,并整合Nacos、【Docker】安装 Seata Server
3、准备一个服务提供方(seata-b-server)的接口和服务调用方(seata-a-server)接口,本文两个服务之间调用通过OpenFegin,可参考前文。
二、服务提供方(seata-b-server)准备
- 提供TestTccController类
package com.cyun.seata.b.controller;
import com.cyun.core.result.ResultVO;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
/**
* 服务提供者,提供接口(TCC)
*
* @author He PanFu
* @date 2022-03-17 20:38:18
*/
@Slf4j
@RestController
@RequestMapping("/test/tcc")
@RequiredArgsConstructor
public class TestTccController {
@PostMapping("/add")
public ResultVO prepare(@RequestBody BusinessActionContext context, @RequestParam("id") String id,
@RequestParam("name") String name) {
log.info("请求进入准备阶段,参数信息:id={},name={}", id, name);
return ResultVO.ok();
}
@PostMapping("/add/commit")
public boolean commitTcc(@RequestBody BusinessActionContext context) {
log.info("请求进入提交阶段,xid = {}", context.getXid());
return true;
}
@PostMapping("/add/cancel")
public boolean cancel(@RequestBody BusinessActionContext context) {
// 这里写中间件、非关系型数据库的回滚操作
log.info("请求进入回滚阶段,xid = {}", context.getXid());
return true;
}
}
三、服务调用方准备
- 提供测试类入口TestTccController
package com.cyun.seata.a.controller;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.cyun.core.result.ResultVO;
import com.cyun.seata.a.entity.A;
import com.cyun.seata.a.feign.service.ISeataBServerService;
import com.cyun.seata.a.feign.service.ISeataTccBServerService;
import com.cyun.seata.a.service.IAService;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 服务调用者:测试入口
*
* @author He PanFu
* @date 2022-03-17 20:38:18
*/
@Slf4j
@RestController
@RequestMapping("/test/tcc")
@RequiredArgsConstructor
public class TestTccController {
private final ISeataTccBServerService seataTccBServerService;
@GetMapping(value = "/add")
@GlobalTransactional
public ResultVO testAdd() {
seataTccBServerService.prepare(null,"1","张三");
return ResultVO.ok();
}
}
- OpenFeig服务
package com.cyun.seata.a.feign.service;
import com.cyun.core.result.ResultVO;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
/**
* seata-b-server 服务提供的接口
*
* @author He PanFu
* @date 2022-03-17 21:07:40
*/
@SuppressWarnings("All")
@FeignClient(value = "seata-b-server")
@LocalTCC
public interface ISeataTccBServerService {
@PostMapping("/seata_b_server/test/tcc/add")
@TwoPhaseBusinessAction(name = "prepare", commitMethod = "commitTcc", rollbackMethod = "cancel")
public ResultVO prepare(@RequestBody BusinessActionContext context, @BusinessActionContextParameter(paramName = "id") @RequestParam("id") String id,
@BusinessActionContextParameter(paramName = "name") @RequestParam("name") String name);
@PostMapping("/seata_b_server/test/tcc/add/commit")
public boolean commitTcc(@RequestBody BusinessActionContext context);
@PostMapping("/seata_b_server/test/tcc/add/cancel")
public boolean cancel(@RequestBody BusinessActionContext context);
}
- 相关介绍
@LocalTCC:适用于SpringCloud+Feign模式下的TCC
@TwoPhaseBusinessAction:注解try方法,其中name为当前tcc方法的bean名称,写方法名便可(记得全局唯一),commitMethod指向提交方法,rollbackMethod指向事务回滚方法。指定好三个方法之后,seata会根据全局事务的成功或失败,去帮我们自动调用提交方法或者回滚方法。
@BusinessActionContextParameter:注解可以将参数传递到二阶段(commitMethod/rollbackMethod)的方法。
BusinessActionContext:便是指TCC事务上下文
四、启动服务,调用测试接口后效果
- 服务提供者控制台日子
五、问题总结
- 自定义commit()和自定义cancel()方法必须是boolean返回值类型,不然会报错,并且一直重试。
- 提供者提供的接口不能是get类型的,否则也会报错,并会直接进入到自定义cancel()方法。提示
六、拓展
相关文章推荐:
Seata分布式事务方案TCC模式