事务
ACID 特性
- 原子性(
A
)
- 事务操作要么都做(提交),要么都不做(回滚)。事务是访问并更新数据库各种数据项的一个程序执行单元,是一个不可分割的单位。
- 通过
undo log
来实现回滚操作,undo log
记录事务的 DML
操作,当回滚时,回放事务 DML
操作的逆运算。
- 在
MVCC
中,undo log
记录事务 DML
操作提交后产生的行数据版本信息。
- 一致性(
C
)
- 一致性指事务将数据库从一种一致性状态转变为下一种一致性的状态,在事务执行前后,数据库完整性约束没有被破坏。
- 例如:一个表的姓名有唯一约束,如果一个事务对姓名进行修改,但是在事务提交或事务回滚后,表中的姓名变得不唯一了,这样就破坏了一致性。
- 逻辑上的一致性。
- 例如:
A
给 B
汇款 100
万:1. 获取 A
的余额。2. 将 A
的余额减去 100
万,并应用到数据库中。3. 获取 B
的余额。4. 将 B
的余额加上 100
万,并应用到数据库中。
- 不能出现
A
的余额已经减去了 100
万,但是 B
的余额没有加上 100
万。
- 逻辑上的一致性是可以被破坏的 → 设置不同程度的隔离级别适当地破坏逻辑上的一致性。
- 一致性由原子性、隔离性以及持久性共同来维护。
- 隔离性(
I
)
- 隔离性表示各个事务之间相互影响的程度。
- 目的:防止多个并发事务交叉执行导致数据不一致。
- 通过设置不同程度的隔离级别,适当地破环逻辑上的一致性,从而提高并发性能。
- 通过
MVCC
和锁来实现。
MVCC
:多版本并发控制,它不使用锁来限制读操作,从而实现高效并发读性能。
- 锁用来处理并发
DML
操作,数据库中提供粒度锁的策略,针对表(聚簇索引 B+
树)、页(聚簇索引 B+
树叶子节点)、行(叶子节点中某一段记录行)三种粒度加锁。
- 持久性(
D
)
- 事务一旦完成,要将数据所做的变更记录下来,包括数据存储和多副本的网络备份。
- 事务提交后,事务
DML
操作将会持久化 → 写入 redo log
磁盘文件:哪一个页、页偏移值、具体数据,即使发生宕机等故障,数据库也能将数据恢复。
Buffer Pool
是基于内存的,如果数据库宕机,数据就会丢失。
- 对数据库的操作,会先更新内存,标记脏页,然后记录
redo log
日志。
redo log
记录的是物理日志,确保 Buffer Pool
中提交事务的数据是安全的。
undo log
和 redo log
的区别:
undo log
记录某个事务开始前的数据状态,记录的是更新之前的值。
redo log
记录某次事务完成后的数据状态,记录的是更新之后的值。
隔离级别
- 隔离级别指的是事务之间相互影响的程度。
- 目的:通过适度破坏逻辑上的一致性,提升
MySQL
并发处理 SQL
语句的性能。
ISO
和 ANIS SQL
标准制定了四种事务隔离级别的标准,MySQL innodb
默认支持的隔离级别是 repeatable read
(可重复读)。
read uncommitted
(读未提交)
- 读操作不做任何处理。
- 写操作加
X
锁,写锁在事务提交或回滚后释放。
- 会出现脏读、不可重复读、幻读。
read committed
(读已提交)(RC
)
- 读操作使用
MVCC
,读取最新版本的行数据。
- 写操作加
X
锁。
- 解决了脏读,会出现不可重复读、幻读。
repeatable read
(可重复读)(RR
)
- 读操作使用
MVCC
,读取事务开始前版本的行数据。
- 写操作加
X
锁。
- 解决了脏读、不可重复读,只会出现幻读。
serializable
(可串行化)
- 读操作加
S
锁,所以事务都是串行化执行,此时隔离级别最严苛。
- 写操作加
X
锁。
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET @@tx_isolation =