Milo源码解析(六)

解析Confirm阶段

回到InitiatorMiloTransactionHandler,当try阶段执行完成之后,此时整个事务是处于中间状态的,我们需要做就是从此前保存的事务日志中获取到参与者的目标类和方法,从而执行对应的confirm方法,同样在confirm执行的阶段需要全部成功,失败或者部分失败都不算完成。
在这里插入图片描述
进入到confirmPhase方法,更新事务日志将阶段修改为CONFIRMING,发起者将查询出来整个事务的所有参与者,本案例一共有三个,分别是订单服务的支付方法、库存服务的扣减方法和账户服务的扣减方法。reflectExecute方法通过反射执行目标类和目标方法(目标方法就是我们使用@MiloTCC注解confirmMethod的值)并将参数传递过去,这里的参数和执行try方法时一样,同时需要我们使用者保证confirm方法的幂等性。此外需要提到一点的就是反射执行的bean实例是通过SpringBeanUtils获取的,这也是当初将容器上下文保存到SpringBeanUtils的原因。
在这里插入图片描述
在这里插入图片描述
我们用集合保存了confirm阶段各个参与者的执行结果,如果全部执行成功那么发起者服务将会删除该事务日志,否则更新是事务日志保存执行失败的参与者。因为我们是通过捕获异常来知道执行结果的,所有需要confirm方法在执行失败时主动将异常抛出去。如果真的发生了部分执行成功或者全部失败的情况,那么将由定时任务去处理事务日志。此时整个订单支付的流程已经结束,假设支付服务的confirm成功了,但是账户和库存服务的扣减都没有成功,那么这次调用支付的结果是会得到支付完成的订单结果,此时账户和库存对应的扣减值处于中间状态,也就是冻结状态,并不影响整个的业务,账户和库存已经在try阶段扣去该扣去的值,后面也会由定时任务去处理这些未完成的事务,后面会详细介绍Milo事务日志处理定时器MiloTransactionLogHandleScheduled。
在这里插入图片描述
在这里插入图片描述
我们了解了发起者是怎么处理confirm阶段的,那么提供者是如何处理的呢?通过前面的代码截图可以看到在执行反射远程调用时,传递的事务上下文的阶段是CONFIRMING,角色是CONSUMER,那么最终会进入到ProviderMiloTransactionHandler,switch case的值将会是CONFIRMING,提供者根据事务上下文获取到事务日志,处理的方式和发起者一样,调用了confirmPhase方法,只是对于提供者来说事务日志的参与者只有自己一个。
在这里插入图片描述

解析Cancel阶段

cancel阶段的处理逻辑其实和confirm是非常相似的,只是触发的条件是在tryPhase和confirmPhase抛出异常时处理,cancelPhase方法也是从事务日志中取出所有参与者,而通过reflectExecute反射去执行远程调用时,事务上线文的阶段为CANCELING,角色仍然是CONSUMER,所以远程调用对于提供者来说同样会进入到ProviderMiloTransactionHandler
在这里插入图片描述
在这里插入图片描述
在提供者处理CANCELING阶段时也是通过事务日志执行目标类的cancel方法。这里需要注意的是,在执行cancel方法时我们会将阶段还是READY的事务日志过滤掉不处理,通知向外抛出异常,因为发起者支付服务在try阶段远程调用账户服务时,可能会存在超时错误的可能,那么支付服务的openfeign就已经熔断了,紧接着就进入cancel阶段,那么此时账户服务还没有执行完try阶段,就接收到了cancel阶段的指令,这显然不合理,通过抛出异常使得整个事务日志维持在try阶段失败,如果处理的话,那么提供者将会在没有执行完try阶段的时候就去执行cancel阶段,假如cancel阶段执行完成,这个事务执行完了cancel阶段,事务日志都删除掉了。紧接着账户服务的try阶段准备执行完成了,创建了事务日志,就会存在账户资金冻结的中间状态,那么这个中间状态下一步是执行confirm呢?还是cancel呢?这时事务自恢复定时任务的时候将不知道如何处理,所以milo对于事务日志的阶段流程定义的非常清楚,cancel和confirm阶段的执行必须是在所有参与者的try阶段执行之后。那么又会抛出一个问题,try阶段一直超时不执行完成怎么办呢?milo的做法是90秒超时视为try阶段失败(后面在定时任务讲解会解释),那如果90秒都没有结束怎么办呢?首先我认为这是一个钻牛角尖的问题,使用者可以将时间配置更长,使用者也可以自己的框架中处理这种超时问题,否则对于这种中彩票概率的事情,最好的处理方法就是不处理。
在这里插入图片描述

我的公众号

Alt

发布了122 篇原创文章 · 获赞 127 · 访问量 93万+

猜你喜欢

转载自blog.csdn.net/u010739551/article/details/102895518
今日推荐