四、Mysql事务及其隔离级别

1.前置问题

  1. 什么是事务?事务的特性?
  2. 隔离级别有几种?为什么要有不同的隔离级别?
  3. 隔离级别是会话级的吗?
  4. mvcc是什么?为什么要有mvcc?
  5. mvcc和隔离级别的关系?
  6. mvcc的两种同构模型?
  7. redo log和undo log的区别?

2. 事务

应用系统在操作数据库时,往往需要进行组合操作,事务的存在是把这种组合操作视为一个原子操作,要么全部执行成功,要么全不执行。事务通过原子性来保证数据库状态的一致性。

事务四个特性

1)原子性:在事务中的数据库操作视为一个整体,要么全部执行,要么全不执行,避免只执行了部分操作,导致数据不一致;
2)一致性:在事务操作前和操作后,数据库的数据始终处于一致性状态。例如,转账操作,需要保证转账前后,转账双方的总额不变;
3)隔离性:也称并发控制;多个事务并发访问数据库时,不同事务的操作在执行时要相互隔离,在提交前对其他事务不可见;
4)持久性:事务一旦提交,就是永久的。即便数据库宕机也能恢复。

3. 事务隔离性

考虑到并发的性能,MySql等数据库在实现隔离性性的时候并没有完全真正的隔离。目前有四种事务隔离级别标准:

insert into t (id, name) values(1, "wang") // 初始化语句

1)读未提交

一个事务读到了另一个事务未提交的修改,这种现象被称为脏读;

时间顺序 事务一 事务二
1 BEGIN
2 select name from t where id = 1
// 结果为“wang”
BEGIN
3 update t set name="王" where id = 1
4 select name from t where id = 1
// 结果为“王”
5 COMMIT COMMIT
2)读已提交

一个事务读到了另一个事务已提交的修改,这种现象被称为不可重复读;

时间顺序 事务一 事务二
1 BEGIN
2 select name from t where id = 1
// 结果为“wang”
BEGIN
3 update t set name="wang" where id = 1
4 select name from t where id = 1
// 结果为“wang”
5 COMMIT
6 select name from t where id = 1
// 结果为“王”
7 COMMIT
3)可重复读

一个事务读取的结果不会受另一个事务(无论是否提交)影响。

时间顺序 事务一 事务二
1 BEGIN
2 select name from t where id = 1
// 结果为“wang”
BEGIN
3 update t set name="wang" where id = 1
4 select name from t where id = 1
// 结果为“wang”
5 COMMIT
6 select name from t where id = 1
// 结果为“wang”
7 COMMIT

但是可重复读无法解决幻读问题,即当事务A读取某个范围的记录时,事务B在该范围内插入了新的记录,那么事务A再次读取该范围记录时,就会发现新增了记录。

4)串行化

数据库强制事务串行执行来避免并发问题。

附:隔离级别表
隔离级别 脏读 不可重复读 幻读
读未提交 Y Y Y
读已提交 N Y Y
可重复读 N N Y
串行化 N N N

4. InnoDb事务隔离性的实现

InnoDB通过MVCC(多版本并发控制机制)来实现读未提交,读已提交,可重复读级别的非阻塞读。并且通过间隙锁可使可重复读级别避免部分幻读问题。

1)MVCC的InnoDB实现
2)RR级别下,通过间隙锁解决部分幻读问题

5. redo log和undo log

redo log undo log
作用 保证事务的持久性 帮助事务回滚和支持mvcc功能
记录内容 物理日志,记录的是页的物理修改操作 逻辑日志,根据每行记录进行记录

参考

  1. MySql技术内幕 InnoDB存储引擎 第七章

你可能感兴趣的:(四、Mysql事务及其隔离级别)