正文
DTM 通知所有参与事务的各个 RM,给每个 RM 发送 prepare 消息。RM
接收到消息后进入准备阶段后,要么直接返回失败,要么创建并执行本地事务,写本地事务日志(redo 和 undo 日志),但是
不提交(此处只保留最后一步耗时最少的提交操作给第二阶段执行)。
第二阶段是提交/回滚阶段。
DTM 收到 RM 准备阶段的失败消息或者获取 RM 返回消息超时,则直接给 RM 发送回滚(rollback)消息,否则发送提交(commit)消息。RM 根据 TM 的指令执行提交或者回滚,执行完成后释放所有事务处理过程中使用的锁(最后阶段释放锁)。
数据库层面的两阶段提交,可以用来保证分布式事务的一致性,使得使用者使用分布式事务和单机事务一样方便。而两阶段提交的另外一种实现,即TCC(Try-Confirm-Cancel),
也就是业务层面的柔性事务。 交易和账务分离的一致性实现,就是采用这种柔性事务来完成的。首先来说说柔性事务,它涉及 3 个模块,主业务、从业务 和
活动管理器(协作者)。
下面这张图是有关柔性事务一张经典的图。
第一阶段:
主业务服务分别调用所有从业务服务的 try 操作,并在活动管理器中记录所有从业务服务。当所有从业务服务 try 成功或者某个从业务服务 try 失败时,进入第二阶段。
第二阶段:
活动管理器根据第一阶段从业务服务的 try 结果来执行 confirm 或 cancel 操作。如果第一阶段所有从业务服务都 try 成功,则协作者调用所有从业务服务的 confirm 操作,否则,调用所有从业务服务的 cancel 操作。
在第二阶段中,confirm 和 cancel 同样存在失败情况,所以需要对这两种情况做 异常处理以保证数据一致性。
1. Confirm 失败:则回滚所有 confirm 操作并执行 cancel 操作。
2. Cancel 失败:从业务服务需要提供自动 cancel 机制,以保证 cancel 成功。
如果对应到交易和账务分离的项目中,流程如下:
第一阶段:
主业务服务调用交易和账务执行try的操作,交易开启事务,做业务上的判断和写入,但是不提交事务。账务层面做资源的锁定。