`
MauerSu
  • 浏览: 521724 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多
源:http://fucheng.blog.51cto.com/2404495/1619359
评:
repeatable-read是Mysql默认事务隔离级别!能解决脏读以及不可重复读的问题,但可能出现幻读的情况

不可重复读:在一个未提交的事务里,二次查询结果可能不相同,因为在这个事务执行过程中,外面的   事务可能对这个数据集进行了修改并提交!
幻读:一个事务在操作过程中!有别的事务对此数据集进行了修改并提交,但这些操作第一个事务读不到,等到这个事务提交的时候,便有可能引起明明插入的数据没有查询到,但却出现插入重复的错误!
不可重复读与幻读的区别:
不可重复读是能读到其它事务已经提交的数据,幻读是读不到其它事务已提交的数据!
间隙锁:间隙锁主要用来防止幻读,用在repeatable-read隔离级别下,指的是当对数据进行条件,范围检索时,对其范围内也许并存在的值进行加锁!当查询的索引含有唯一属性(唯一索引,主键索引)时,Innodb存储引擎会对next-key lock进行优化,将其降为record lock,即仅锁住索引本身,而不是范围!若是普通辅助索引,则会使用传统的next-key lock进行范围锁定!


/*
幻读案例:有个表 (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;
*/  
                                                                                
总结:
表a
id
3
5
6
9

在运用间隙锁的过程中,(-00 +00为负正无穷大)
如果条件为where a=5这样的条件,则间隙锁锁住的范围为(-00,3),(3,5),(5,6),(6,9),(9,+00) 
如果条件为where a>5,则间隙锁锁住的范围为(5,+00)
如果为select max(id),则锁住的范围为(max(id),+00)
另外在测试间隙锁的过程中遇到了innodb锁全表,全表所有间隙上锁的情况!这篇博文里的提到:
http://blog.itpub.net/29254281/viewspace-1401413/


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

相关推荐

    MySQL可重复读级别能够解决幻读吗

    MySQL的可重复读(Repeatable Read)隔离级别是其事务管理机制的一部分,旨在解决数据库并发操作中的一些问题,如脏读、不可重复读和幻读。然而,标题中提出的问题在于,可重复读隔离级别是否能完全防止幻读。在这个...

    mysql-一些常见的mysql死锁案例-笔记记录.zip

    在可重复读隔离级别下,MySQL使用Next-Key Locks(包括行锁和间隙锁)来防止幻读,但这也可能导致死锁的可能性增加。 死锁的常见案例包括但不限于以下几种: 1. **资源顺序获取**:事务A持有资源1并请求资源2,而...

    一次MYSQL死锁分析案例1

    - **隔离级别**: 此案例中提到的隔离级别是可重复读(Repeatable Read),这是InnoDB存储引擎的默认隔离级别,它能防止幻读现象,但可能会导致死锁。 - **索引**: 死锁涉及到的是`order_pay_status`表的主键索引。 ...

    mysql死锁的一些案例

    InnoDB为防止幻读使用了间隙锁(Gap Lock),有时会导致死锁。比如,T1锁定一个范围内的行,T2尝试锁定另一个范围,但这两个范围有交集,导致死锁。 为了预防和解决死锁,我们可以采取以下策略: 1. 避免长时间...

    MySQL事务基础知识讲解,结合具体案例分析并发事务下常见的问题讲解视频!

    3. 幻读:在一个事务中,两次执行同样的查询,但第二次出现了在第一次查询时不存在的新记录,通常是由于间隙锁策略的不同导致的。 视频将通过实际案例来演示这些问题,例如银行转账操作,两个并发的转账事务可能会...

    一个最不可思议的MySQL死锁分析1

    next key锁是InnoDB的一种锁定策略,它不仅锁定索引记录,还锁定记录之间的间隙,以防止幻读。 为了理解这个死锁的成因,我们需要进一步研究Delete操作的加锁逻辑。在InnoDB中,当进行DELETE操作时,系统会先获取...

    MySQL 数据库的基础知识.zip

    在MySQL中,你可以设置事务隔离级别,如读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE)。理解事务的ACID属性(原子性、一致性、隔离性和持久性)...

    mysql死锁分析

    在`RR`(Repeatable Read)隔离级别下,`DELETE`操作默认使用`nextkey lock`来锁定目标记录及其之前的间隙,以防其他事务在此间隙中插入新记录。 这种锁机制可以防止幻读现象,但在某些情况下也可能导致死锁。例如...

Global site tag (gtag.js) - Google Analytics