MySQL事务的隔离级别
MySQL事务的隔离级别
READ UNCOMMITTED
Read Uncommitted(读未提交)是隔离级别最低的一种事务级别。在这种隔离级别下,一个事务会读到另一个事务更新后但未提交的数据,如果另一个事务回滚,那么当前事务读到的数据就是脏数据,这就是脏读(Dirty Read)。
READ COMMITTED
Read Committed(读已提交)是指当前事务只能读取到其它已提交的事务,未提交的事务数据不会读取。
在Read Committed隔离级别下,一个事务可能会遇到不可重复读(Non Repeatable Read)的问题。
不可重复读是指,在一个事务内,多次读同一数据,在这个事务还没有结束时,如果另一个事务恰好修改了这个数据,那么,在第一个事务中,两次读取的数据就可能不一致。
REPEATABLE READ(MySQL默认)
REPEATABLE READ是在READ COMMITTED的基础上,限制事务自身不受到外部影响(不管途中其他事务是否commit更改操作),对数据的查询结果始终与本身事务的操作结果一致。
在Repeatable Read(可重复读)隔离级别下,一个事务可能会遇到幻读(Phantom Read)的问题。
幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。
Serializable
Serializable(串行化)是最严格的隔离级别。在Serializable隔离级别下,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。
虽然Serializable隔离级别下的事务具有最高的安全性,但是,由于事务是串行执行,所以效率会大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用Serializable隔离级别。
默认隔离级别
如果没有指定隔离级别,数据库就会使用默认的隔离级别。在MySQL中,如果使用InnoDB,默认的隔离级别是Repeatable-Read。
查看MySQL的事务隔离级别
查看MySQL数据库默认的事务隔离机制
show VARIABLES LIKE ‘tx_isolation’;
tx_isolation 是变量,这个变量也可能是transaction_isolation
查看系统级的隔离级别和会话级的隔离级别
select @@global.tx_isolation, @@tx_isolation;
设置MySQL的事务隔离级别
设置innodb的事务级别方法是:set 作用域 transaction isolation level 事务隔离级别
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
//全局的
mysql> set global transaction isolation level read committed;
//当前会话
mysql> set session transaction isolation level read committed;
使用哪种隔离级别
一般情况下第一种(Read UnCommitted)和第四种(Serializable)不会使用。
一般互联网项目使用:读已提交(Read Commited)这个隔离级别。
REPEATABLE READ是在READ COMMITTED的基础上,限制事务自身不受到外部影响(不管期间其他事务是否commit更改操作),对数据的多次查询结果始终与本身事务的操作结果一致。
下面分析下Read Commited(RC)、Repeatable Read(RR)。
- 在RR隔离级别下,存在间隙锁,导致出现死锁的几率比RC大的多。
- 在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行。
- 在RC隔离级别下,半一致性读(semi-consistent)特性增加了update操作的并发性。