天机阁

事务的隔离级别

2022-07-13 · 2 min read
MySQL

SQL 标准中的4中隔离级别

SQL标准定义了四个隔离级别如下:

  • READ UNCOMMITTED(未提交读):允许读取尚未提交的变更数据。
  • READ COMMITTED(已提交读):允许读取事务已经提交的数据。
  • REPEATABLE READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本身事务所修改。
  • SERIALIZABLE(可串行化):最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰。

并发事务执行过程中可以发生的现象

隔离级别 脏读 不可重复读 幻读
READ UNCOMMITTED 可能 可能 可能
READ COMMITTED 不可能 可能 可能
REPEATABLE READ 不可能 不可能 可能
SERIALIZABLE 不可能 不可能 不可能

说明:

  • READ UNCOMMITTED 隔离级别下,可能发生脏读、不可重复读和幻读现象;
  • READ COMMITTED 隔离级别下,可能发生不可重复读和幻读现象,但是不可能发生脏读现象;
  • REPEATABLE READ 隔离级别下,可能发生幻读现象,但不可能发生脏读和不可重复读现象;
  • SERIALIZABLE 隔离级别下,上述现象都不可能发生。

因为脏写现象对数据一致性影响太严重了,所以无论哪种隔离级别,都不允许脏写的情况发生。

MySQL 的默认隔离级别

MySQL InnoDB 存储引擎默认的隔离级别是 REPEATABLE READ(可重复读)。我们可以通过 SELECT @@tx_isolation; 命令来查看,MySQL 8.0之后该命令改为 SELECT @@transaction_isolation;

mysql> SELECT @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |
+-------------------------+
1 row in set (0.00 sec)

MySQL 在 REPEATABLE READ 隔离级别下,是可以解决幻读问题发生的,主要有下面两种情况:

  • 快照读:这种情况下是可以解决幻读的,它是由 MVCC 机制来解决的。
  • 当前读:这种情况下并不保证避免幻读,需要应用使用加锁读来保证,这个加锁读使用到的机制就是 Next-Key Lock(Record Lock + Gap Lock)。