五TCC-transaction的事务执行流程
五 TCC-transaction的事务执行流程
四 TCC-transaction的事务执行流程
tcc调用方法是以@Compensable来标识的,spring bean方式调用时,会被事件拦截器和资源协调拦截器拦截。
事件拦截器会控制整个try-confirm-cancel流程,以下对这三个流程进行详细说明。
4.1 try流程
A1 开启主事务。 #
事件上下文为空,走主事务流程,开启主事务,即创建主事件和缓存主事件。
A2 创建参与方A。 #
详见事件参与方
A3 保存事件A及参与方A(持久化)。 #
注意:参与方A是作为事件A的组成部分存储的,因此一次存储操作即可
A4 执行本地try方法 #
本地try方法,里面可能包含其他逻辑,这里只关注分支事务的远程调用。
A4.1 调用B服务try方法 #
- A4.1.1 添加参与方B
- A4.1.2 保存参与方B(持久化)
- A4.1.3 RPC调用B服务+事件上下文状态:TRYING,执行服务B上分支事务try阶段
这里涉及到事件上下文,在微服务中传递,传递方式与具体微服务类型有关,感兴趣可查看
- A4.1.4 更新参与方状态为TRY_SUCCESS
调用一个B服务的rpc-clientB的try方法,此方法被@EnableTcc修饰,从而被资源协调拦截器拦截。
如CapitalFeignClient中写法
@FeignClient(name = "capital", url = "http://localhost:8082/tcc-transaction-http-capital/")
public interface CapitalFeignClient {
@EnableTcc
@RequestMapping(value = "/tradeOrder/record", method = RequestMethod.POST)
@ResponseBody
String record(@RequestBody CapitalTradeOrderDto tradeOrderDto);
}
A4.2 调用C服务try方法 #
- A4.2.1 添加参与方C
- A4.2.2 保存参与方C(持久化)
- A4.2.3 RPC调用C服务+事件上下文状态:TRYING,执行服务C上分支事务try阶段
- A4.2.4 更新参与方状态为TRY_SUCCESS
调用一个C服务的rpc-clientC的try方法,此方法被@EnableTcc修饰,从而被资源协调拦截器拦截。
如RedPacketFeignClient中写法
@FeignClient(name = "redPacket", url = "http://localhost:8083/tcc-transaction-http-redpacket/")
public interface RedPacketFeignClient {
@EnableTcc
@RequestMapping(value = "/tradeOrder/record", method = RequestMethod.POST)
@ResponseBody
String record(@RequestBody RedPacketTradeOrderDto tradeOrderDto);
}
A5 更新参与方A状态为TRY_SUCCESS #
A6 执行confirm/cancel流程。 #
在B服务中try阶段 #
源码可查看:
CompensableTransactionInterceptor.providerMethodProceed(try逻辑)
ResourceCoordinatorInterceptor.interceptTransactionContextMethod方法(添加参与方)
B1 开启分支事务 #
事件上下文非空,走分支事务流程,开启分支主事务,即构建分支事件。
B2 添加参与方B #
B3 保存化事件B和参与方B(持久化) #
注意:参与方B是作为事件B的组成部分存储的,因此一次存储操作即可
B4 执行本地try方法 #
B5 更新参与方状态为TRY_SUCCESS #
B6 更新事件状态为TRY_SUCCESS #
B7 更新事件B(持久化) #
在C服务中try阶段 #
源码可查看:
CompensableTransactionInterceptor.providerMethodProceed(try逻辑)
ResourceCoordinatorInterceptor.interceptTransactionContextMethod方法(添加参与方)
C1 开启分支事务 #
事件上下文非空,走分支事务流程,开启分支主事务,即构建分支事件。
C2 添加参与方C #
C3 保存化事件C和参与方C(持久化) #
注意:参与方C是作为事件B的组成部分存储的,因此一次存储操作即可