分布式事务-TXLCN
一、什么是事务?
1.事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。数据库事务提供了一种机制,可用来将一系列数据库更改归入一个逻辑操作。更改数据库后,所做的更改可以作为一个单元进行提交或取消。事务可确保遵循原子性、一致性、隔离性和持续性(ACID)这几种属性,以使数据能够正确地提交到数据库中。
简单而言,事务提供了一种“要么全部做,要么什么都不做”的机制。
二、事务的四大特性
1.事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
2.原子性(Atomicity)
一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
3.一致性(Consistency)
事务必须是使数据库从一个一致性状态变到另一个一致性状态。
4. 隔离性(Isolation)
并发环境下,当不同的事务同时操作相同数据时,每个事务都有各自的完整数据空间。
5.持久性(Durability)
只要事务完成,状态将得到永久保存,崩溃可修复。
三、什么是分布式事务?
分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点上。
四、为什么需要分布式事务?
分布式事务的出现是为了保证分布式系统的事务一致性。
五、分布式事务的理论知识
C---- 数据一致性(consistency)
如果系统对一个写操作返回成功,那么后续所有读请求都应该读取到这个写操作的新数据。
如果系统对一个写操作返回失败,那么后续所有读请求都应该读取不到这个写操作的数据。
A---- 服务可用性(availability)
所有读写操作都会在一定时间内得到响应,可终止,不会一直阻塞等待。
P---- 分区容错性(partition-tolerance)
在网络分区的情况下,被分隔的节点仍能正常对外服务
六、分布式事务与本地事务的区别
本地事务:负责保证同一个服务的同一个数据库的操作同时成功与失败
分布式事务:负责保证不同服务的同一个或不同数据库的操作的成功与失败(可以允许不同步)
总的来说,分布式事务相当于作为管理者角色站在服务的层面去管理各个服务的本地事务提交
七、分布式事务框架---TX-LCN
TX-LCN定位于一款事务协调性框架,框架其本身并不操作事务,而是基于对事务的协调从而达到事务一致性的效果。
LCN模式:通过代理Connection的方式实现对本地事务的操作,然后在由TxManager统一协调控制事务。当本地事务提交回滚或者关闭连接时将会执行假操作,该代理的连接将由LCN连接池管理。
八、框架原理
TxClient:作为模块的依赖框架,提供TX-LCN的支持,用于控制事务的发起方和参与方;TxManager:作为分布式事务的控制方。
九、核心步骤
1、创建事务组 ------ 事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,然后拿到事务标示GroupId的过程。
2、加入事务组 ------ 事务参与方执行完业务方法以后,将该模块的事务信息通知给TxManager的操作
3、通知事务组 ------ 事务发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager,TxManager将根据事务最终状态和事务组的信息来通知相应的事务参与方提交或回滚事务,并返回结果给事务发起方。
十、整合分布式事务
1、构建TxManager(TM),添加分布式依赖
<!--分布式事务管理器-->
<dependency>
<groupId>com.codingapi.txlcn</groupId>
<artifactId>txlcn-tm</artifactId>
</dependency>
2、配置事物配置文件
spring.application.name=tx-manager
server.port=7970
spring.profiles.active=dev
# TM后台登陆密码,默认值为codingapi;访问路径http://127.0.0.1:7970/admin/index.html
tx-lcn.manager.admin-key=admin
# TM监听IP. 默认为 127.0.0.1
tx-lcn.manager.host=127.0.0.1
# TM监听Socket端口. 默认为 ${server.port} - 100
#tx-lcn.manager.port=8070
# 心跳检测时间(ms)
tx-lcn.manager.heart-time=15000
# 分布式事务执行总时间
tx-lcn.manager.dtx-time=30000
#参数延迟删除时间单位ms
tx-lcn.message.netty.attr-delay-time=10000
tx-lcn.manager.concurrent-level=128
# 开启日志,记录在数据库的t_logger表格中
tx-lcn.logger.enabled=true
logging.level.com.codingapi=debug
tx-lcn.logger.driver-class-name=${spring.datasource.driver-class-name}
tx-lcn.logger.jdbc-url=${spring.datasource.url}
tx-lcn.logger.username=${spring.datasource.username}
tx-lcn.logger.password=${spring.datasource.password}
#redis 主机
spring.redis.host=127.0.0.1
#redis 端口
spring.redis.port=6379
#redis 密码
#spring.redis.password=
3、启动配上配置事物服务
@EnableTransactionManagerServer
启动后访问界面如下:
十一、整合分布式事务
- 编写服务提供接口
- 编写feign调用另外一个服务接口
- 服务A中插入数据库,在服务B中也插入数据库
- 调用服务A接口,同时观察数据存入数据情况。
发现在没有实物的情况下,事物的一致性没有得到保证
十二、开始事物
在调用和被调用的服务上分别加上
@EnableDistributedTransaction
同时在需要加入事物处理的方法上加上本地事物注解和分布式事物注解
@LcnTransaction //分布式事务注解
@Transactional //本地事务注解
此时可以保证事物保持一致性,当被调用的事物发生异常时,调用方的事物也会随之回滚,从而确保事物的一致性。
至此,分布式事物搭建整合完毕!