一、分布式事务的概述
1、本地事务
1)、事务介绍
事务是访问数据库的一个操作序列(一条或多条程序语句),数据库应用系统通过事务集来完成对数据库的存取。事务的正确执行使得数据库从一种状态转换为另一种状态。
事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)的缩写。
事务ACID特性:
-
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。- EG:转账,张三—>李四
- 1.张三账户扣除200
- 2.李四账户新增200
- EG:转账,张三—>李四
-
一致性(Consistency)
一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。- 转账:
- 张三账户:1000 ---- 800
- 李四账户:1500 ---- 1700
- 转账:
-
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离 -
持久性Durability)
这是最好理解的一个特性:持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。(完成的事务是系统永久的部分,对系统的影响是永久性的,该修改即使出现致命的系统故障也将一直保持)
2)、并发下事务会产生的问题
脏读:一个事务读取到了另一个事务还没有提交的数据。
不可重复读:一个事务内多次查询显示的数据不一致。
幻读:一个事务内多次查询的结果返回的条数不一致。
3)、事务的隔离级别
√:可能出现 ×:不会出现
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted) | √ | √ | √ |
读已提交(read-committed) | × | √ | √ |
可重复读(repeatable-read) | × | × | √ |
序列化(serializable) | × | × | × |
2、分布式事务
事务的参与者、支持事务的服务器、资源服务器以及事务的管理器分别位于分布式系统的不同节点之上。
分布式事务三种场景:
场景一:不同的服务访问各自的数据库
场景二:不同的服务访问同一数据库
场景三:同一服务内,访问不同的数据库
3、分布式事务基础理论
1)、CAP理论
在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。
-
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
-
可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
-
分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
在分布式系统中,我们不可能在保证高可用(服务)的同时又保证强一致性,我们能够容忍在一致性或可用性方面有一些损失。
CAP原则的精髓就是要么AP,要么CP。在实际应用中一般偏重AP,保证服务的可用性,但凡涉及到和金额相关的要保证强一致性。
2)、Base理论
BASE全称:Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)。
Base 理论是对 CAP 中一致性和可用性权衡的结果, 其来源于对大规模互联网系统分布式实践的总结,是基于CAP定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性, 但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
基本可用:是指分布式系统在出现不可预知故障的时候,允许损失部分可用性
注意, 这绝不等价于系统不可用。比如:
-
(1)响应时间上的损失。正常情况下,一个在线搜索引擎需要在0.5S秒之内返回给用户相应的查询结果, 但由于出现故障,查询结果的响应时间增加了1-2秒
-
(2)系统功能上的损失。正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候, 由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面
软状态:指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时
最终一致性:强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
二、分布式事务的解决方案
1、柔性事务和刚性事务
刚性事务:满足ACID特性的事务
在分布式系统中无法满足,一般指在单机服务器中的事务
柔性事务:满足Base理论的事务(基本可用,最终一致性)
柔性事务分为:2PC类型、补偿型、异步确保型、最大努力通知型
2、分布式事务管理模型
3、2PC
整个分布式事务完成分为两个阶段:
准备阶段(prepare)
事务管理者会向事务的每个参与者发送一个是否准备好的请求,当事务的参与者都确认准备好,就会进入到第二阶段。
执行阶段(commit)
每个事务参与者进行提交,提交后向事务管理者确认已提交
4、3PC
在2PC基础上的改进
-
引入了超时机制
加入事务管理者向事务参与者发起提议,参与者挂了,事务管理者得不到参与者的响应就会一直等待,假如参与者8s内没有响应,事务管理者默认参与者没有准备好,就会通知其他参与者取消事务提交。 -
在第一阶段在第三阶段引入了预提交(提交前准备阶段)
当所有参与者都进行了预提交,会进行第三阶段提交阶段
5、TCC
TCC是Try-Confirm-Cancel的简称
- Try阶段:尝试执行,完成所有业务检查(占有执行资源)
- Confirm阶段:确认执行业务
- Cancel阶段:取消执行(释放占有的执行资源)
三、Tx-LCN介绍
LCN分布式事务框架是一款事务协调性的框架。
- TM(TxManager):事务管理器
- TC(IxClient):我们自己的服务
Tx-LCN进行分布式事务管理,有多种方式:lcn模式、 txc模式、tcc模式
四、TxLCN使用
1、案例说明
-
订单服务:提交订单,调用库存服务修改库存
-
库存服务:修改库存
2、搭建服务注册与发现中心
-
创建SpringBoot应用,添加Eureka-server
-
配置application.yml
server: port: 8761 spring: application: name: eureka eureka: client: register-with-eureka: false fetch-registry: false service-url: defaultzone: http://localhost:8761/eureka
-
启动类添加
@EnableEurekaServer
注解@SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }
3、搭建TM
-
按照TM的要求建库建表
create database db_txlcn; use db_txlcn; CREATE TABLE `t_tx_exception` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `group_id` varchar(<