您的位置:首页 > 其它

InnoDB事务锁之行锁-insert唯一二级索引-隐式锁转换案例

2018-02-10 10:41 267 查看
1、表结构CREATE TABLE `t3` (
`id` int(11) NOT NULL,
`id2` int(11) DEFAULT NULL,
`id3` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id2` (`id2`,`id3`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;2、数据mysql> select *from t3;
+----+------+------+
| id | id2 | id3 |
+----+------+------+
| 6 | 1 | 1 |
| 8 | 1 | 2 |
| 10 | 1 | 3 |
| 7 | 4 | 4 |
| 1 | 6 | 6 |
| 4 | 7 | 7 |
+----+------+------+
6 rows in set (0.00 sec)3、插入第一条语句mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t3 values(11,1,4);
Query OK, 1 row affected (0.00 sec)该事务中,唯一二级索引(1,4,11)加的是隐式锁,即没有加锁的。
4、插入第二条语句mysql> insert into t3 values(12,1,4);
ERROR 1062 (23000): Duplicate entry '1-4' for key 'id2'此时先将(1,4,11)隐式锁转换成显示锁,该锁是X类型的LOCK_REC_NOT_GAP锁;然后因为重复key,对其加S类型的LOCK_ORDINARY锁。
5、
流程原理图,参考之前章节。
6、总结
InnoDB实现了一个延迟加锁机制,减少加锁的数量,即隐式锁。
隐式锁特点:
1、只有在很可能发生冲突时才加锁,减少锁的数量
2、隐式锁针对被修改的B+tree记录,因此都是记录类型的锁,即只锁记录,不可能是gap或next-key锁。
3、insert操作只加隐式锁,不需要加显示锁
4、update、delete在查询时,直接对查到的主键加显示锁,对其他索引加隐式锁。
   理论上,可以对主键加隐式锁的。提前加显示锁应该是为了减少死锁的发生。insert、update、delete操作都是从主键开始的,因此对主键加锁可以有效阻止死锁
   https://www.cnblogs.com/yuyue2014/p/5527923.html
5、锁兼容判断条件是不同事务之间;强度判断是在相同事务之间

6、当前事务insert into t3 values(11,1,4);insert into t3 values(12,1,4);
     第二个语句先将上一条的隐式锁转换成显示锁;
     然后在加S类型的next-key锁:因为是同一个事务,不存在兼容性;
     虽然X类型强度大于S类型,但是X类型是LOCK_REC_NOT_GAP,而S类型的是LOCK_ORDINARY,可以加锁成功;
     判断强度时,只判断同模式的,即next-key与next-key,not gap与not gap
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐