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的事务隔离级别,那么有必要介绍不同事务隔离级别下锁定机制的差异。
期待...