TCC是一种分布式的事务的方案,将一个事务分成了TRY-CANCEL-CONFIRM三个阶段:
在TCC中,存在着两个比较关键的问题,那就是空回滚和悬挂的问题。
这两个问题处理不好,都可能会导致一个分布式事务没办法保证最终一致性。有一个办法,可以一次性的解决以上两个问题,那就是——引入分布式事务记录表。
有了这张表,每一个参与者,都可以在本地事务执行的过程中,同时记录一次分布式事务的操作记录。
这张表中有两个关键的字段,一个是tx_id用于保存本次处理的事务ID,还有一个就是state,用于记录本次事务的执行状态。至于其他的字段,比如一些业务数据,执行时间、业务场景啥的,就自己想记录上就记录啥。
CREATE TABLE `distribute_transaction` (
`tx_id` varchar(128) NOT NULL COMMENT '事务id',
`state` int(1) DEFAULT NULL COMMENT '事务状态,0:try,1:confirm,2:cancel',
PRIMARY KEY (`tx_id`) U
)
有了这张表以后,我们在做try、cancel和confirm操作之后,都需要在本地事务中创建或者修改这条记录。一条记录的状态机如下:
空回滚解决:当一个参与者接到一次Cancel请求的时候,先去distributetransaction表中根据txid查询是否有try的记录,如果没有,则进行一次空回滚即可。并在distribute_transaction中创建一条记录,状态标记为cancel。
事务悬挂解决:当一个参与者接到一次Try请求的时候,先去distributetransaction表中根据txid查询是否有记录,如果当前存在,并且记录的状态是cancel,则拒绝本次try请求。
但是需要注意的是,上面的请求过程,需要做好并发控制。
有了这张表,我们还可以基于他做幂等控制,每次try-cancel-confirm请求来的时候,都可以到这张表中查一下,然后做幂等控制。