没有合适的资源?快使用搜索试试~ 我知道了~
从本地事务介绍开始,介绍分布式事务、理论及解决方案。使读者了解分布式事务产生的原因,了解几种分布式事务解决方案:XA、TCC、消息事务、TA、SAGA,了解分布式事务各种解决方案的优缺点和使用场景,以及学会使用Seata来解决分布式事务
资源推荐
资源详情
资源评论
分布式事务
0.课前准备
0.1.学习目标
了解分布式事务产生的原因
知道几种分布式事务解决方案:XA、TCC、消息事务、TA、SAGA
知道分布式事务各种解决方案的优缺点和使用场景
学会使用Seata来解决分布式事务
0.2.知识准备
会使用SpringBoot
会使用SpringCloud的Eureka和Feign组件
知道mysql的传统事务特性
1.什么是分布式事务
要了解分布式事务,必须先了解本地事务。
1.1.本地事务
本地事务,是指传统的单机数据库事务,必须具备ACID原则:
原子性(A)
所谓的原子性就是说,在整个事务中的所有操作,要么全部完成,要么全部不做,没有中间状态。对于事务
在执行中发生错误,所有的操作都会被回滚,整个事务就像从没被执行过一样。
一致性(C)
事务的执行必须保证系统的一致性,在事务开始之前和事务结束以后,数据库的完整性没有被破坏,就拿转
账为例,A有500元,B有500元,如果在一个事务里A成功转给B50元,那么不管发生什么,那么最后A账户
和B账户的数据之和必须是1000元。
隔离性(I)
所谓的隔离性就是说,事务与事务之间不会互相影响,一个事务的中间状态不会被其他事务感知。数据库保
证隔离性包括四种不同的隔离级别:
Read Uncommitted(读取未提交内容)
Read Committed(读取提交内容)
Repeatable Read(可重读)
Serializable(可串行化)
持久性(D)
所谓的持久性,就是说一旦事务提交了,那么事务对数据所做的变更就完全保存在了数据库中,即使发生停
电,系统宕机也是如此。
因为在传统项目中,项目部署基本是单点式:即单个服务器和单个数据库。这种情况下,数据库本身的事务
机制就能保证ACID的原则,这样的事务就是本地事务。
概括来讲,单个服务与单个数据库的架构中,产生的事务都是本地事务。
其中原子性和持久性就要靠undo和redo 日志来实现。
1.2.undo和redo
本小节参考内容:mysqlops
在数据库系统中,既有存放数据的文件,也有存放日志的文件。日志在内存中也是有缓存Log buffer,也有
磁盘文件log file。
MySQL中的日志文件,有这么两种与事务有关:undo日志与redo日志。
1.2.1.undo日志
数据库事务具备原子性(Atomicity),如果事务执行失败,需要把数据回滚。
事务同时还具备持久性(Durability),事务对数据所做的变更就完全保存在了数据库,不能因为故障而丢
失。
原子性可以利用undo日志来实现。
Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到Undo Log。然
后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数
据恢复到事务开始之前的状态。
数据库写入数据到磁盘之前,会把数据先缓存在内存中,事务提交时才会写入磁盘中。
用Undo Log实现原子性和持久化的事务的简化过程:
假设有A、B两个数据,值分别为1,2。
A. 事务开始.
B. 记录A=1到undo log.
C. 修改A=3.
D. 记录B=2到undo log.
E. 修改B=4.
F. 将undo log写到磁盘。
G. 将数据写到磁盘。
H. 事务提交
如何保证持久性?
事务提交前,会把修改数据到磁盘前,也就是说只要事务提交了,数据肯定持久化了。
如何保证原子性?
每次对数据库修改,都会把修改前数据记录在undo log,那么需要回滚时,可以读取undo log,
恢复数据。
若系统在G和H之间崩溃
此时事务并未提交,需要回滚。而undo log已经被持久化,可以根据undo log来恢复数据
若系统在G之前崩溃
此时数据并未持久化到硬盘,依然保持在事务之前的状态
缺陷:每个事务提交前将数据和Undo Log写入磁盘,这样会导致大量的磁盘IO,因此性能很低。
如果能够将数据缓存一段时间,就能减少IO提高性能。但是这样就会丧失事务的持久性。因此引入了另外一
种机制来实现持久化,即Redo Log.
1.2.2.redo日志
和Undo Log相反,Redo Log记录的是新数据的备份。在事务提交前,只要将Redo Log持久化即可,不需要
将数据持久化,减少了IO的次数。
先来看下基本原理:
Undo + Redo事务的简化过程
假设有A、B两个数据,值分别为1,2
A. 事务开始.
B. 记录A=1到undo log buffer.
C. 修改A=3.
D. 记录A=3到redo log buffer.
E. 记录B=2到undo log buffer.
F. 修改B=4.
G. 记录B=4到redo log buffer.
H. 将undo log写入磁盘
I. 将redo log写入磁盘
J. 事务提交
安全和性能问题
如何保证原子性?
如果在事务提交前故障,通过undo log日志恢复数据。如果undo log都还没写入,那么数据就尚未持久
化,无需回滚
如何保证持久化?
大家会发现,这里并没有出现数据的持久化。因为数据已经写入redo log,而redo log持久化到了硬
盘,因此只要到了步骤 I 以后,事务是可以提交的。
内存中的数据库数据何时持久化到磁盘?
因为redo log已经持久化,因此数据库数据写入磁盘与否影响不大,不过为了避免出现脏数据(内存中
与磁盘不一致),事务提交后也会将内存数据刷入磁盘(也可以按照固设定的频率刷新内存数据到磁盘
中)。
redo log何时写入磁盘
redo log会在事务提交之前,或者redo log buffer满了的时候写入磁盘
这里存在两个问题:
问题1:之前是写undo和数据库数据到硬盘,现在是写undo和redo到磁盘,似乎没有减少IO次数
数据库数据写入是随机IO,性能很差
redo log在初始化时会开辟一段连续的空间,写入是顺序IO,性能很好
实际上undo log并不是直接写入磁盘,而是先写入到redo log buffer中,当redo log持久化时,undo
log就同时持久化到硬盘了。
因此事务提交前,只需要对redo log持久化即可。
另外,redo log并不是写入一次就持久化一次,redo log在内存中也有自己的缓冲池: redo log buffer 。
每次写redo log都是写入到buffer,在提交时一次性持久化到磁盘,减少IO次数。
问题2:redo log 数据是写入内存buffer中,当buffer满或者事务提交时,将buffer数据写入磁盘。
redo log中记录的数据,有可能包含尚未提交事务,如果此时数据库崩溃,那么如何完成数据恢复?
数据恢复有两种策略:
恢复时,只重做已经提交了的事务
恢复时,重做所有事务包括未提交的事务和回滚了的事务。然后通过Undo Log回滚那些未提交的事务
Inodb引擎采用的是第二种方案,因此undo log要在 redo log前持久化
1.2.3.总结
最后总结一下:
undo log 记录更新前数据,用于保证事务原子性
redo log 记录更新后数据,用于保证事务的持久性
redo log有自己的内存buffer,先写入到buffer,事务提交时写入磁盘
redo log持久化之后,意味着事务是可提交的
1.3.分布式事务
分布式事务,就是指不是在单个服务或单个数据库架构下,产生的事务:
跨数据源的分布式事务
跨服务的分布式事务
综合情况
1)跨数据源
随着业务数据规模的快速发展,数据量越来越大,单库单表逐渐成为瓶颈。所以我们对数据库进行了水平拆
分,将原单库单表拆分成数据库分片,于是就产生了跨数据库事务问题。
2)跨服务
在业务发展初期,“一块大饼”的单业务系统架构,能满足基本的业务需求。但是随着业务的快速发展,系统
的访问量和业务复杂程度都在快速增长,单系统架构逐渐成为业务发展瓶颈,解决业务系统的高耦合、可伸
缩问题的需求越来越强烈。
如下图所示,按照面向服务(SOA)的架构的设计原则,将单业务系统拆分成多个业务系统,降低了各系统
之间的耦合度,使不同的业务系统专注于自身业务,更有利于业务的发展和系统容量的伸缩。
剩余50页未读,继续阅读
资源评论
AE86Jag
- 粉丝: 43
- 资源: 18
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功