MySQL隔离级别

  • READ UNCOMMITED 读未提交
  • READ COMMMICTED 读已提交
  • REPEATABLE READ 重复读
  • SERIALIZABLE 串行化

举例些简单的例子, 实际业务可能和其有些差别, 不过毕竟万变不离其宗.

模拟前提

表结构

common.png

填充数据

1
2
3
4
5
6
7
8
9
INSERT INTO
`t_student_score` (`name`, `score`, `course_id`)
VALUES
('小A', 1, 1),('小A', 2, 2),('小A', 3, 3),('小B', 4, 1),
('小B', 5, 2),('小B', 6, 3),('小C', 4, 1),('小C', 8, 2),
('小C', 9, 3),( '小D', 4, 1),('小D', 11, 2),('小D', 12, 3),
('小A', 1, 4),('小B', 2, 4),('小C', 3, 4),('小D', 4, 4),
('小A', 1, 5),('小B', 2, 5),('小C', 3, 5),('小D', 4, 5),
('小A', 1, 6),('小B', 2, 6),('小C', 3, 6),('小D', 4, 6);

READ UNCOMMITED 读未提交

mysql默认是RR级别, 需要手动切换到RU级别, RU级别下会发生脏读现象, 导致读取到错误数据影响业务.

READ-UNCOMMITTED.png

READ COMMMICTED 读已提交

需要先手动切换到RC级别

避免脏读

RC级别下能避免脏读, 下面先看看是如何避免脏读的.

READ-COMMITTED-page1.png

重复读取出现问题

RC级别下, 重复读取数据会有问题, 所以RC级别也可以叫”不可重复读” 下面看看实例.

READ-COMMITTED-page2.png

REPEATABLE READ 重复读

MySQL innoDB引擎默认的隔离级别

避免重复读问题

RR级别下能避免重复读问题, 所以RR级别叫做”可重复读”, 下面看看它是如何避免重复读问题的.

REPEATABLE-READ-page1.png

幻读问题

MySQL innoDB RR级别下利用 next-key locks 避免了幻读, 为了模拟幻读, 这里切换到RU级别

REPEATABLE-READ-page2.png

避免幻读问题

下面演示在RR级别下的MySQL innoDB引擎是如何避免幻读的.

REPEATABLE-READ-page3.png

SERIALIZABLE 串行化

需要先手动切换到SI级别
串行化是最大程度的避免的并行问题, 因为它利用锁, 把并行操作全转换成串行, 如果某个事务占用了某资源, 其他事务将被阻塞, 直到锁被释放.

SERIALIZABLE.png