# tx-distribute **Repository Path**: back1968/tx-distribute ## Basic Information - **Project Name**: tx-distribute - **Description**: 分布式事务 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-03-20 - **Last Updated**: 2022-03-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: 分布式事务 ## README # tx-distribute #### 介绍 为了更好的了解分布式事务底层的原理,参考了别人造的轮子,整理了思路,自己也造了个轮子 倒不是说特意去造轮子,而是只有自己在参与并敲击的过程中,才能对分布式事务有更深入的理解 出于学习的目的,造的轮子是很粗糙的,从而也感知到了,实际生产中,分布式事务需要考虑的点是非常多的 #### 感悟 这次手撸的分布式事务主要涉及到这几个主键: TC:事务协调器(独立服务部署) TM:事务管理器(嵌入到具体应用服务) TM嵌入具体应用服务,通过切面获取到数据库connection的控制权,并且在提交事务之前将本地事务情况汇报给远程TC, 然后重开一条线程进入等待状态,等待远程TC唤醒线程。 TC通过全局事务id进行分组,当最后一个事务提交汇报后, 判断该分组下的所有事务状态是否都是成功,如果有其中一个失败,那么便下发全部回滚的状态,应用服务通过监听,接收 到回滚状态,唤醒事务线程执行回滚。 在这过程中有几个点需要注意: 1.如何判断所有事务都已经提交,这里的处理方式是,人为自己定义哪个微服务接口是最后一个提交的事务,这样在实际开发中 肯定是行不通的。 2.如果TC挂了话怎么办? 如果TC挂了,服务应用得不到唤醒,那么所有事务都将阻塞得不到执行,当然是可以通过设置失效时间, 但是这样也是有风险的,高并发的情况下,事务都阻塞几秒,直接影响到整个数据库的吞吐量,IOPS吃满整个服务会变得巨卡, 这个在生产环境也不是没有遇到过,最后处理的方式是杀死线程,但是这样又可能产生脏数据 3.如果某个业务链很长,分支很杂,通过注解方式实现的分布式事务,其实是很被动的,因为这样会导致整个事务非常大并且不可控制, 其实可以考虑通过面向编程的方式,将事务的颗粒度细腻到具体的执行sql,根据具体的业务,来判断是否需要独立执行职务, 因为有些特殊的业务,它是不需要回滚的 #### 软件架构 SpringBoot、Mybatis-plus、Netty #### 使用说明 1.数据库配置文件根据自己的实际情况修改 2.sql: SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for biz_order -- ---------------------------- DROP TABLE IF EXISTS `biz_order`; CREATE TABLE `biz_order` ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `num` bigint(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 49 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Table structure for biz_payment -- ---------------------------- DROP TABLE IF EXISTS `biz_payment`; CREATE TABLE `biz_payment` ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `payment` int(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1500842273092759626 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact; SET FOREIGN_KEY_CHECKS = 1; ![输入图片说明](tx.jpg)