mysql插入意向锁测试

mysql插入意向锁测试,第1张

1、表结构

    CREATE TABLE `reno` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(10) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8

2、表数据

    insert into reno select 5, 'aa'

  insert into reno select 7, 'bb'

  insert into reno select 9, 'cc'

  insert into reno select 18, 'dd'

  insert into reno select 23, 'ee'

  insert into reno select 30, 'ff'

  insert into reno select 40, 'gg'

  insert into reno select 45, 'hh'

  insert into reno select 99, 'ii'

3、两种尝试

    下面两种方案都会造成阻塞,我理解都是事务1获取到了间隙锁,事务2获取插入意向锁阻塞,但是“show engine INNODB status\G”输出结果不一样,

第一种方案

    事务1 lock_mode X locks gap before rec 我理解是间隙锁

    事务2 lock_mode X locks gap before rec insert intention waiting 我理解是获取插入意向锁

第二种方案

    事务1  trx id 9821 lock_mode X 我理解是 Next key锁

    事务2 lock_mode X insert intention waiting 我理解是获取插入意向锁

我的疑问 为什么两个方案,事务1获取的锁,以及事务2获取的锁都是不一样的呢 

第一种方案 

mysql 为并发事务同时对一条记录进行读写时,提出了两种解决方案:

1)使用 mvcc 的方法,实现多事务的并发读写,但是这种读只是“快照读”,一般读的是历史版本数据,还有一种是“当前读”,一般加锁实现“当前读”,或者 insert、update、delete 也是当前读。

2)使用加锁的方法,锁分为共享锁(读锁),排他锁(写锁)

快照读:就是select

当前读:特殊的读 *** 作,插入/更新/删除 *** 作,属于当前读,处理的都是当前的数据,需要加锁。

mysql 在 RR 级别怎么处理幻读的呢?一般来说,RR 级别通过 mvcc 机制,保证读到低于后面事务的数据。但是 select for update 不会触发 mvcc,它是当前读。如果后面事务插入数据并提交,那么在 RR 级别就会读到插入的数据。所以,mysql 使用 行锁 + gap 锁(简称 next-key 锁)来防止当前读的时候插入。

Gap Lock在InnoDB的唯一作用就是防止其他事务的插入 *** 作,以此防止幻读的发生。

Innodb自动使用间隙锁的条件:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11307142.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存