一、環境準備
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模式