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

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
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__ 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值