日期:2014-05-16  浏览次数:20770 次

Mysql事务隔离水平(Isolation Levels)简介
Mysql有4种事务隔离水平(Transaction Isolation Levels)

1.未提交读(Read Uncommitted):一个事务可能读取到其他会话中未提交事务修改的数据,就是脏读(dirty read)。这种隔离水平是没有实际意义的。

2.提交读(Read Committed):从字面理解的意思是事务只能读取到已经提交的数据。在High Performance Mysql一书的解释是:
引用
a transaction will see only those changes made by transactions that were already committed when it began, and its changes won’t be visible to others until it has committed.


单纯从字面上还是有点绕口。其实比较简单,就是一个事务里面如果有对一个数据的多次访问,Read Committed不保证每次访问的结果都一样。如果别的会话在该事务2次访问数据之间对该数据进行了修改或者删除,2次访问就会得到不一样的结果。

所以这个隔离水平也叫nonrepeatable read(不可重复读)。Oracle缺省使用这个隔离水平

3. 可重复读(Repeated Read):可重复读,结合上面对提交读的解释,这个隔离水平就很好理解。一个事务里面如果有对一个数据的多次访问,Repeated Read会保证在该事务内所有访问结果都一致,不管其他会话是否尝试对该数据修改或者删除。Mysql的InnoDB缺省使用这个隔离水平

可重复读可能会带来幻读(phantom read)的问题。幻读是指一个事务里面如果有对一个数据的多次访问,后一次的访问读到别的会话插入的数据。(别的会话刚好插入一个数据满足改访问的where条件)。

但是mysql innodb通过multiversion concurrency control技术保证了不会发生幻读的情况。

4. 串行(Serializable):串行化访问,每次读都需要获得表级共享锁,读写相互都会阻塞。串行的最大问题的是并发能力非常低。

--------------------华丽的分割线---------------------------
为了更好的区别Read Committed和Repeated Read,读者可以参考这个例子:

1) 首先建立一个表:
CREATE TABLE t1(id int,value int);
INSERT t1 VALUES(1,1);

2) 测试Read Committed会出现不可重复读的情况
同时打开两个的会话,在第一个会话执行以下的sql:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 设置Read Committed级别
START TRANSACTION;
    SELECT * FROM t1; 
   
    select sleep(10); -- 休眠10秒,等待另一个会话修改数据
   
    SELECT * FROM t1;  
commit  ;

在第一个会话休眠期期间,在第二个会话执行以下的SQL:
update t1 set value = 2 where id =1;

第一个会话结束后,可以看到两个SELECT的结果是不一样的,第二次select被第二个会话的数据修改影响了。

3)测试Repeated Read的可重复读能力
在会话一执行以下SQL:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- 设置 repeatable read级别
START TRANSACTION;
    SELECT * FROM t1; 
   
    select sleep(10); -- 休眠10秒,等待另一个会话修改数据
   
    SELECT * FROM t1;  
Commit  ;

在第一个会话休眠期期间,在第二个会话执行以下的SQL:
update t1 set value = 3 where id =1;

第一个会话结束后,可以看到两个SELECT的结果是完全一样的,而且第二个会话没有被阻塞,并不是串行的读写来保证可重复读。

1 楼 whitesock 2011-04-29  
MySQL的事务隔离级别和锁定机制存在紧密联系,既然介绍了MySQL的事务隔离级别,那么有必要介绍不同事务隔离级别下锁定机制的差异。
2 楼 iyfd 2011-04-29  
whitesock 写道
MySQL的事务隔离级别和锁定机制存在紧密联系,既然介绍了MySQL的事务隔离级别,那么有必要介绍不同事务隔离级别下锁定机制的差异。


多谢提醒,后面会抽时间再写的。
3 楼 Technoboy 2011-04-30  
whitesock 写道
MySQL的事务隔离级别和锁定机制存在紧密联系,既然介绍了MySQL的事务隔离级别,那么有必要介绍不同事务隔离级别下锁定机制的差异。

期待...