码迷,mamicode.com
首页 > 数据库 > 详细

mysql repeatable-read 一次利用间隙锁解决幻读案例

时间:2015-03-11 19:58:52      阅读:6275      评论:0      收藏:0      [点我收藏+]

标签:mysql 间隙锁 repeatable-read

repeatable-read是Mysql默认事务隔离级别!能解决脏读以及不可重复读的问题,但可能出现幻读的情况


不可重复读:在一个未提交的事务里,二次查询结果可能不相同,因为在这个事务执行过程中,外面的   事务可能对这个数据集进行了修改并提交!

幻读:一个事务在操作过程中!有别的事务对此数据集进行了修改并提交,但这些操作第一个事务读不到,等到这个事务提交的时候,便有可能引起明明插入的数据没有查询到,但却出现插入重复的错误!

不可重复读与幻读的区别:

不可重复读是能读到其它事务已经提交的数据,幻读是读不到其它事务已提交的数据!

间隙锁:间隙锁主要用来防止幻读,用在repeatable-read隔离级别下,指的是当对数据进行条件,范围检索时,对其范围内也许并存在的值进行加锁!

比如where id <8 lock in share mode,则对8以下的值都加间隙锁,

select max(id) ........lock in share mode,则会对max(id)以上的并不存在值加间隙锁!  

select * from e where id=20 lock in share mode 则只会对id=20加锁!(此时可能只是普通的共享锁了)

select * from e lock in share mode; 则对整个e加上间隙表锁!



幻读案例:有个表(id字段为唯一约束)每次插入前需查询这字段的最大值,然后再取最大值+1插入!

事务1:                                                                            事务2:

select max(id) from e;                                                      insert into e values (11)

10                                                                                       commit;

insert into e values (11)

commit;

ERROR 1062 (23000): Duplicate entry ‘11‘ for key ‘id‘

在上述事务1中明明查询最大值为10,但插入最大值+1的时候却报错!


解决方案:利用mysql间隙锁

事务1:                                                                              事务2:

select max(id) from e lock in share mode;  

(此时会对id为10以上的所有不存在的值加间隙锁)                   

10                                                                                       insert into e values (11);

insert into e values (11)                                                   commit;  此时提交会一处于等待状态,

commit;

                                                                                           


本文出自 “夫臣” 博客,请务必保留此出处http://fucheng.blog.51cto.com/2404495/1619359

mysql repeatable-read 一次利用间隙锁解决幻读案例

标签:mysql 间隙锁 repeatable-read

原文地址:http://fucheng.blog.51cto.com/2404495/1619359

(1)
(6)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!