mysql

mysql 隔离级别

2020-11-14  本文已影响0人  修行者12138

在并发环境下,mysql存在脏读、不可重复读、幻读等数据一致性问题。

脏读

事务1读到了事务2未提交的修改,也就是读到了脏数据

不可重复读

事务1和事务2读取了同一行数据,然后事务2做了修改并提交,然后事务1再次读取该行数据,读到了事务2已提交的修改,也就是事务1不可以重复读取同一行数据,否则读到的结果可能不一样

幻读

事务1读取某一个范围内的数据(比如有10行),然后事务2向这个范围新增或删除了行,事务1第二次读的时候,发现这个范围内的数据变化了,也就是事务1不可以重复读取同一个范围内的数据,否则读到的结果可能不一样

以上问题,如果由应用程序控制,会相当复杂,所以mysql提供了4种隔离级别来解决以上问题

READ UNCOMMITTED(未提交读)

该隔离级别下,事务可以读到其他事务未提交的修改,该隔离级别性能较差,而且缺点很明显。

READ COMMITTED(提交读)

该隔离级别下,事务只能读到其他事务已提交的修改,可以解决脏读的问题。
(这个级别也叫不可重复读 NONREPEATABLE READ)

REPEATABLE READ(可重复读)

该隔离级别下,同一个事务多次读取同一行数据的结果一定是一致的,可以解决脏读和不可重复读的问题。
REPEATABLE READ是mysql默认的隔离级别,不过不少项目(比如笔者所在项目)的默认隔离级别是READ COMMITTED,因为同一个事务重复读取同一行数据的业务场景(如统计报表)比较少见,不必要为少见的业务场景牺牲整体的性能

SERIALIZABLE(可串行化)

该隔离级别下,事务被强制串行执行,可以解决脏读、不可重复读和幻读的问题,SERIALIZABLE会在读取的每一行数据都加锁,可能导致大量的超时和锁争用。

总结

1.通常来说,隔离级别越高,一致性越可靠,但存储引擎的开销越大,支持的并发越低
2.隔离级别是存储引擎实现的,而不是mysql服务层实现的,不同存储引擎的实现方式不一样
3.在同一个事务中混用存储引擎是不可靠的,比如同一个事务中同时使用了innodb(事务型)和myisam(非事务型)的表,如果该事务需要回滚,myisam的表的变更无法撤销

隔离级别 脏读可能性 不可重复读可能性 幻读可能性
READ UNCOMMITTED yes yes yes
READ COMMITTED no yes yes
REPEATABLE READ no no yes
SERIALIZABLE no no no
上一篇下一篇

猜你喜欢

热点阅读