1.什么是分布式事务?
在单个系统中,为了保证数据库的事务性,我们简单的使用@Transactional注解就可以实现,但是由于业务需要,或者是为了提高效率,对数据库进行分库分表操作,或者说在微服务中,服务A调用了服务B,两个服务使用了不同的数据库表,简单理解来说,业务的操作由原来的一个库一张表可能变成了多个库多张表。
如果有个业务,需要同时对多个库的表进行操作,要保证这两个库的数据准确,因此产生了分布式事务,要么这两个库的操作 同时失败,要么同时更新。
2.怎么解决分布式事务?
2.1 使用LCN
2.1.1 什么是LCN
官网地址:github.com/codingapi/t…
中文文档,5.x版本:www.codingapi.com/docs/txlcn-…
LCN是Lock(锁定事务单元),Confirm(确认事务模块状态),Notify(通知事务)三个单词的简写
2.1.2 LCN事务控制原理
TX_LCN由两个模块组成:TxManager和TxClient
核心步骤:
- 创建事务组
在事务发起方开始执行业务代码之前先调用Txmanager创建事务组对象,然后拿到事务标识 GroupId
- 加入事务组
参与方在执行完业务方法以后,将该模块的事务信息通知给TxManager的操作
- 通知事务组
发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager,Txmanager将根据事务最终状态和事务组的信息来通知相应的参与模块提交或回滚事务,并赶回结果给事务发起方
2.1.3 搭建Tm服务器
1.流程:从官网下载源码包,解压,修改配置文件和pom文件,maven打包,执行jar包
1.1 下载源码包:github.com/codingapi/t… ,选择版本【我使用的5.0.2版本】
1.2 创建本地数据库及其表,使用tm提供的现成sql文件
tm服务器依赖redis,数据库,需要根据需求修改配置文件
1.1 pom打包方式修改:注释掉最后的docker构建,添加springboot的maven打包:
org.springframework.boot
spring-boot-maven-plugin
org.apache.maven.plugins
maven-jar-plugin
2.6
com.codingapi.txlcn.tm.TMApplication
true
lib/
./
config/**
1.2 application.properties配置文件修改:
spring.application.name=TransactionManager
server.port=7970
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tx-manager?characterEncoding=UTF-8
spring.datasource.username=youruser
spring.datasource.password=yourpassword
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=create
1.3 启动jar包之后,可访问http://127.0.0.1:7970/admin/index.html#/ 查看后台管理页面,默认登录密码为 codingapi
也可以在配置文件中指定
2.1.4 创建Tc客户端
1.创建一个springboot,名为A项目,引入tc依赖
com.codingapi.txlcn
txlcn-tc
5.0.2.RELEASE
com.codingapi.txlcn
txlcn-txmsg-netty
5.0.2.RELEASE
2.增加tm的配置文件:
tx-lcn.client.manager-address=127.0.0.1:8070
tx-lcn.logger.enabled=true
3.重复上面的操作,创建一个名为B的项目
4.A项目调用B项目,使用分布式锁,在A和B项目的启动类上使用 @EnableDistributedTransaction 开启分布式事务
6.启动A,B两个项目,测试分布式事务,一旦有异常,A,B都会回滚数据,且在A的库中会新增一个t_log表,能查看事务组信息