背景
网上查看了很多关于分布式事务的文章,比如TCC事务补偿方案,MQ的一致性解决方案等等,也有一些自己提出的设想,在看了之后,自己思考并尝试设计了一套分布式事务处理方案。
大致思想
对事物提交进行暂停(类似于二段提交),即在一次操作中出现的多个事务,各自完成自有逻辑后不直接提交事务,此时去等待并轮询其他事务的结果,若成功则提交,失败或超过一定时长则进行回滚。
具体实现逻辑
如上图:
1、在业务处理层生成tranId,作为此次处理的唯一标识,并根据次标识生成多个事务key存入redis,每个key的值初始都为ready
2、对每个事务启用线程进行异步执行
3、在各自事务处理结束时,若成功,则设置当前事务为完成,即将当前事务key的值变为done;若失败,则设置为失败,即将当前事务key的值变为fail
4、若当前事务失败,则直接提交事务进行回滚;
若当前事务成功:
1)、从redis获取其他事务key的值,判断是否都成功,
2)、若都成功即标识都为done则提交当前事务;
3)、若存在失败即标识存在fail,则回滚当前事务;
4)、若存在还是初始状态的,即标识为read的,表示其他事务还未完成,则进入循环等待,每次循环都从1)开始重新判断
5)、若获取到其他事务key的值为空,表示已超过有效时间,回滚本事务。
由此,基本实现事务的分布式处理。
注意:对于redis失效时间的设定,必须用setex等原子操作,否则容易死锁
存在问题
1、需要异步的事务都启动额外的线程,增加了系统开销
2、对于redis依赖性较强,若redis挂掉,基本都回滚
3、开发成本稍高,对于需要分布事务控制的接口,都需要有特定参数的判断与使用
4、对于不同事务之间需要信息传递的情况处理较麻烦
为了验证上述方案的可行性,特地写了一个项目进行简单尝试,项目地址如下:https://github.com/colinguangyi/dtPlan
有兴趣的朋友可以看看。
另:避免github访问延迟,项目转移至https://gitee.com/zhaolz/dtplan