本地事务特征
本地事务,也就是传统的单机事务。在传统数据库事务中,必须要满足四个原则:ACID
事务的隔离级别
1.读未提交(Read uncommitted):
这种事务隔离级别下,select语句不加锁。
此时,可能读取到不一致的数据,即“读脏 ”。这是并发最高,一致性最差的隔离级别。
2.读已提交(Read committed):
可避免 脏读 的发生。
在互联网大数据量,高并发量的场景下,几乎 不会使用 上述两种隔离级别。
3.可重复读(Repeatable read):
MySql默认隔离级别。
可避免 脏读 、不可重复读 的发生。
4.串行化(Serializable ):
可避免 脏读、不可重复读、幻读 的发生。
不可重复读和幻读是初学者不易分清的概念,总的来说,解决不可重复读的方法是 锁行,解决幻读的方式是 锁表。
分布式事务
分布式事务,就是指不是在单个服务或单个数据库架构下,产生的事务,例如:
-
跨数据源的分布式事务
-
跨服务的分布式事务
-
综合情况
在数据库水平拆分、服务垂直拆分之后,一个业务操作通常要跨多个数据库、服务才能完成。例如电商行业中比较常见的下单付款案例,包括下面几个行为:
-
创建新订单
-
扣减商品库存
-
从用户账户余额扣除金额
完成上面的操作需要访问三个不同的微服务和三个不同的数据库。
Seata的架构
Seata事务管理中有三个重要的角色:
-
TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
-
TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
-
RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<!--版本较低,1.3.0,因此排除-->
<exclusion>
<artifactId>seata-spring-boot-starter</artifactId>
<groupId>io.seata</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<!--seata starter 采用1.4.2版本-->
<version>1.4.2</version>
</dependency>
配置TC地址
配置application.yml
seata:
registry:
type: nacos # 使用nacos作为注册中心
nacos:
server-addr: localhost:8848 # nacos服务地址
group: DEFAULT_GROUP # 默认服务分组
namespace: "" # 默认命名空间
cluster: default # 默认TC集群名称
tx-service-group: ${spring.application.name}-group # 事务组名称
service:
vgroup-mapping:
order-service-group: default # 事务组对应的TC集群名
XA模式
XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准,XA 规范 描述了全局的TM与局部的RM之间的接口,几乎所有主流的数据库都对 XA 规范 提供了支持。
两阶段提交
XA是规范,目前主流数据库都实现了这种规范,实现的原理都是基于两阶段提交。
一阶段:
-
事务协调者通知每个事物参与者执行本地事务
-
本地事务执行完成后报告事务执行状态给事务协调者,此时事务不提交,继续持有数据库锁
二阶段:
-
事务协调者基于一阶段的报告来判断下一步操作
-
如果一阶段都成功,则通知所有事务参与者,提交事务
-
如果一阶段任意一个参与者失败,则通知所有事务参与者回滚事务
-
Seata的XA模型
RM一阶段的工作:
① 注册分支事务到TC
② 执行分支业务sql但不提交
③ 报告执行状态到TC
TC二阶段的工作:
-
TC检测各分支事务执行状态
a.如果都成功,通知所有RM提交事务
b.如果有失败,通知所有RM回滚事务
RM二阶段的工作:
-
接收TC指令,提交或回滚事务
优缺点
XA模式的优点是什么?
-
事务的强一致性,满足ACID原则。
-
常用数据库都支持,实现简单,并且没有代码侵入
XA模式的缺点是什么?
-
因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差
-
依赖关系型数据库实现事务
实现XA模式
Seata的starter已经完成了XA模式的自动装配,实现非常简单,步骤如下:
1)修改application.yml文件(每个参与事务的微服务),开启XA模式:
seata:
data-source-proxy-mode: XA