目录
一、事务回顾
1、什么是事务
**提供一种“要么什么都不做,要么做全套(All or Nothing)”机制。**
2、事务的作用
保证数据的一致性
3、事务ACID四大特性
A:原子性(Atomicity)
一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
C:一致性(Consistency)
事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。
如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。
如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。
I:隔离性(Isolation)
指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。
D:持久性(Durability)
指的是只要事务成功结束,它对数据库所做的更新就必须保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。
4、事务的并发
脏读
事务A读取了事务B更新的数据,事务B未提交并回滚数据,那么A读取到的数据是脏数据
不可重复读
事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
幻读
系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A更改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。
二、Seata之原理简介
1、TC、TM、RM三大组件
2、分布式事务的执行流程
-
TM开启分布式事务(TM向TC注册全局事务记录)
-
换业务场景,编排数据库,服务等事务内资源(RM向TC汇报资源准备状态)
-
TM结束分布式事务,事务一阶段结束(TM通知TC提交/回滚分布式事务)
-
TC汇总事务信息,决定分布式事务是提交还是回滚
-
TC通知所有RM提交/回滚资源,事务二阶段结束。
3、AT模式如何做到对业务的无侵入
3.1、一阶段加载
-
在一阶段,Seata会拦截"业务SQL"
-
1.解析SQL语义,找到“业务SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”
-
2.执行"业务SQL"更新业务数据,在业务数据更新之后,
-
3.其保存成“after image”,最后生成行锁。
-
-
以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。
3.2、二阶段提交
-
二阶段如果顺利提交的话,因为“业务SQL”在一阶段已经提交至数据库,所以Seata框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。
3.3、二阶段回滚
二阶段如果是回滚的话,Seata就需要回滚一阶段执行的“业务SQL”,还原业务数据。
回滚方式便是用“before image”还原业务数据;但在还原前要首先校验脏写,对比“数据库当前业务数据”和“after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。
三、使用SEata添加分布式事务
项目中很多功能都可以添加分布式事务。
比如,支付后处理,首先更新订单状态,之后要获取系统奖励添加到司机账户,这两件事情保证数据一致性,两件事情在不同的模块中,可以使用分布式事务
再比如,乘客下单要做很多事情,但是我们只需要关注保存订单信息与任务调度开启,这两件事件必须保证强一致性,只要乘客下单了,任务调度就必须开启,要么都成功,要么都回滚。
下面我们就引入Seata来解决问题。
1、安装和启动Seata服务
-
Seata可以在Linux操作系统中使用docker安装
-
Seata也可以安装在windows系统(测试)
到Seata官网下载安装文件
2、在使用Seata的相关模块引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2022.0.0.0-RC2</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.7.1</version>
</dependency>
3、在使用Seata的相关模块添加配置
-
添加到bootstrap.properties里面
seata.tx-service-group=tingshu-tx-group
seata.service.vgroup-mapping.tingshu-tx-group=default
seata.service.grouplist.default=127.0.0.1:8091
4、在业务方法添加注解就可以实现分布式事务
@GlobalTransactional
感谢阅读,希望对你有所帮助!!!
标签:回滚,Seata,事务,业务,数据,分布式 From: https://blog.csdn.net/weixin_70206544/article/details/143208795