tx-distribute
项目地址: https://gitee.com/back1968/tx-distribute
介绍
为了更好的了解分布式事务底层的原理,参考了别人造的轮子,整理了思路,自己也造了个轮子 倒不是说特意去造轮子,而是只有自己在参与并敲击的过程中,才能对分布式事务有更深入的理解 出于学习的目的,造的轮子是很粗糙的,从而也感知到了,实际生产中,分布式事务需要考虑的点是非常多的
感悟
这次手撸的分布式事务主要涉及到这几个主键:
TC:事务协调器(独立服务部署)
TM:事务管理器(嵌入到具体应用服务)
TM嵌入具体应用服务,通过切面获取到数据库connection的控制权,并且在提交事务之前将本地事务情况汇报给远程TC, 然后重开一条线程进入等待状态,等待远程TC唤醒线程。 TC通过全局事务id进行分组,当最后一个事务提交汇报后, 判断该分组下的所有事务状态是否都是成功,如果有其中一个失败,那么便下发全部回滚的状态,应用服务通过监听,接收 到回滚状态,唤醒事务线程执行回滚。
在这过程中有几个点需要注意:
1.如何判断所有事务都已经提交,这里的处理方式是,人为自己定义哪个微服务接口是最后一个提交的事务,这样在实际开发中 肯定是行不通的。
2.如果TC挂了话怎么办? 如果TC挂了,服务应用得不到唤醒,那么所有事务都将阻塞得不到执行,当然是可以通过设置失效时间, 但是这样也是有风险的,高并发的情况下,事务都阻塞几秒,直接影响到整个数据库的吞吐量,IOPS吃满整个服务会变得巨卡, 这个在生产环境也不是没有遇到过,最后处理的方式是杀死线程,但是这样又可能产生脏数据
3.如果某个业务链很长,分支很杂,通过注解方式实现的分布式事务,其实是很被动的,因为这样会导致整个事务非常大并且不可控制, 其实可以考虑通过面向编程的方式,将事务的颗粒度细腻到具体的执行sql,根据具体的业务,来判断是否需要独立执行职务, 因为有些特殊的业务,它是不需要回滚的
综上:2PC 是一种尽量保证强一致性的分布式事务,因此它是同步阻塞的,而同步阻塞就导致长久的资源锁定问题,总体而言效率低,并且存在单点故障问题,在极端条件下存在数据不一致的风险。
流程图