一、三种事务模式
1)LCN
基于XA协议,事务提交或回滚的操作由事务管理服务器统一告诉它管理的多个项目,也就是说在A事务,B事务的事务提交操作或回滚操作都是在同一时刻发生,并且要么都提交,要么都回滚。
LCN模式在本地事务的基础上由对事务连接的回滚或提交操作的连接对象的代理对象做出最终事务操作
2)TCC
常用于缓存数据库操作,该事务的提交操作在事务管理服务器告诉它之前,自己由本地事务直接完成事务提交操作,如果事务管理服务器告知需要回滚,那么就执行自己预先写好的回滚方法。
3)TXC
二、分布式事务实现
0)父工程依赖版本
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR12</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>com.codingapi.txlcn</groupId> <artifactId>txlcn-tm</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>com.codingapi.txlcn</groupId> <artifactId>txlcn-tc</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>com.codingapi.txlcn</groupId> <artifactId>txlcn-txmsg-netty</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> </dependencies> </dependencyManagement>
1)搭建事务管理服务器
依赖坐标
<dependencies> <dependency> <groupId>com.codingapi.txlcn</groupId> <artifactId>txlcn-tm</artifactId> </dependency> </dependencies>
配置文件和开启启动类注解
spring.application.name=TransactionManager server.port=7970 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/tx-manager?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=root # redis配置 spring.redis.host=127.0.0.1 # TM服务器IP修改, TC访问TM时,使用的IP地址。必须精确匹配。默认127.0.0.1。代表TC和TM必须在同一个主机中。 tx-lcn.manager.host=127.0.0.1 # TM事务管理端口。默认 0. 是server.port + 100计算得到。 tx-lcn.manager.port=7971 # TM服务器日志系统配置,默认关闭日志系统。需要独立配置日志的存储数据库连接 tx-lcn.logger.enabled=false # 配置TM服务器日志系统数据库连接 tx-lcn.logger.driver-class-name=com.mysql.cj.jdbc.Driver tx-lcn.logger.jdbc-url=jdbc:mysql://localhost:3306/tx-manager?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai tx-lcn.logger.username=root tx-lcn.logger.password=root # 自动创建表格的配置项。可以自动创建日志表格。 #spring.jpa.hibernate.ddl-auto=update # 修改TM服务器的WEB控制台登录密码, 默认登录密码是 codingapi #tx-lcn.manager.admin-key=wollo
数据库手动创建
管理界面,端口为7970
TxManager系统后台TxManager系统后台
2)分布式事务项目依赖
微服务项目想要实现分布式事务管理,引入该依赖,改动配置文件,别忘了开启分布式事务管理的注解;
要想使用TCC模式,额外配置如redis的启动器依赖即可。
<dependency> <groupId>com.codingapi.txlcn</groupId> <artifactId>txlcn-tc</artifactId> </dependency> <dependency> <groupId>com.codingapi.txlcn</groupId> <artifactId>txlcn-txmsg-netty</artifactId> </dependency>
3)项目案例
这里写了一个学生项目,学生的书籍项目,还有一个学生的电话项目;
添加学生的业务远程调用了书籍的服务,电话的服务。
添加学生和添加书籍使用LCN模式,添加电话业务使用TCC模式,
也就是说,有学生表和书籍表,电话存在redis这样的内存数据库中。
①)学生业务层
分布式事务中值得注意的是,如果书籍远程调用出现问题,即使不使用分布式事务管理仍然学生业务回滚;
并且如果redis服务崩了,但其实不影响学生业务,如果都回滚的话会导致所有关联的微服务不可用。
解决这种代码侵入问题和逻辑问题,一是通常指定本地事务的rollbackFor回滚异常;
二是在远程调用方自己捕捉异常处理
②)书籍业务层
③)电话业务层 TCC模式
TCC模式要相对复杂点,因为要编写三个方法,不仅有业务方法,还有预先写好的提交和回滚方法。
提交和回滚方法有命名规范,是业务方法名前加confirm和cancel.