1.在调用主业务服务A的a方法前拦截进行try(在这里try是整个流程的范围,包含了本地服务和远程服务的调用整个过程),并且事物管理器创建事物(主事物的开启生成一个全局事物id。保存到数据库一条事物记录)。
2.登记主业务操作,这里主要是确定主业务服务的confirmMethodName和cancelMethodName 当然还有目标类 targetClass。为了后面根据整个调用链的情况来执行这两个方法的某一个。
3,执行主业务服务A的a方法,这个方法一般有两部分,一是本地业务的处理,二是调用远程服务B的a方法和远程服务C的a方法等
4,当调用远程服务N的n方法前都会进行一次拦截,拦截的目的就是事物管理器来登记参与者(服务调用者登记)这些远程调用。也是为后面根据整个调用链的情况来远程执行confirm方法或cancel方法。
==================================上面都是本地服务内的执行。下面就是远程服务上的执行情况 ======================================================
5,执行远程服务N的n方法,这时还是会被拦截,
5.1,创建一个分支事物对象(全局事物和上面id相同),
5.2,事物管理器来登记参与者(服务提供者登记)。确定了提供者这边的confirmMethodName和cancelMethodName.
注意这些信息都保存在事物对象上并序列化后保存在数据库,为后面调用准备。
6,执行服务N的n方法逻辑处理。到这里远程服务调用结束
==========================================下面又回到主业务服务A的a方法===================
7,执行A服务的a方法后面逻辑
8,回到步骤1的拦截器try里向下执行,如果catch到异常则取出事物对象中的所有参与者并调用cancel方法(注:这里事物对象中不会有步骤5的参与者。步骤5是另一个事件对象保存的);
2.登记主业务操作,这里主要是确定主业务服务的confirmMethodName和cancelMethodName 当然还有目标类 targetClass。为了后面根据整个调用链的情况来执行这两个方法的某一个。
3,执行主业务服务A的a方法,这个方法一般有两部分,一是本地业务的处理,二是调用远程服务B的a方法和远程服务C的a方法等
4,当调用远程服务N的n方法前都会进行一次拦截,拦截的目的就是事物管理器来登记参与者(服务调用者登记)这些远程调用。也是为后面根据整个调用链的情况来远程执行confirm方法或cancel方法。
==================================上面都是本地服务内的执行。下面就是远程服务上的执行情况 ======================================================
5,执行远程服务N的n方法,这时还是会被拦截,
5.1,创建一个分支事物对象(全局事物和上面id相同),
5.2,事物管理器来登记参与者(服务提供者登记)。确定了提供者这边的confirmMethodName和cancelMethodName.
注意这些信息都保存在事物对象上并序列化后保存在数据库,为后面调用准备。
6,执行服务N的n方法逻辑处理。到这里远程服务调用结束
==========================================下面又回到主业务服务A的a方法===================
7,执行A服务的a方法后面逻辑
8,回到步骤1的拦截器try里向下执行,如果catch到异常则取出事物对象中的所有参与者并调用cancel方法(注:这里事物对象中不会有步骤5的参与者。步骤5是另一个事件对象保存的);
如果成功则调用所有参与者是commit方法。修改事物记录的状态,全部成功后删除事物日志这条记录。
注:这里还需要一个定时器去扫描主服务下事物管理记录表中未处理完成的事物(上面过程中只执行了一部分逻辑情况)。利用反射去掉用参于者的 confirm 或cancel 方法
事物对象类结构:
状态:TRYING,CONFIRMING,CANCELLING
事物类型: 主事物,分支事物
事物重试次数
最后更新时间
参与者列表
参与者里主要有 “确认”方法和“取消”方法的 targetClass、方法名、方法参数的class等信息,用于后面的反射调用。
最后附上开源tcc框架:
https://github.com/changmingxie/tcc-transaction/tree/master-1.2.x