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
`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
相关文章推荐
- InnoDB事务锁之行锁-insert二级唯一索引插入duplicate案例
- InnoDB事务锁之行锁-insert唯一二级索引重复键加锁案例
- InnoDB事务锁之行锁-insert二级索引加锁原理图
- InnoDB事务锁之行锁-insert聚集索引加锁流程图
- InnoDB事务锁之行锁-insert加锁原理图-聚集索引
- InnoDB事务锁之行锁-隐式锁转换显示锁举例理解原理
- InnoDB事务锁之行锁-insert加锁-隐式锁转换
- InnoDB事务锁之行锁-insert加锁-隐式锁
- SQL0803N INSERT 语句、UPDATE 语句或由 DELETE 语句导致的外键更新中的一个或多个值无效,因为由 "1" 标识的主键、唯一约束或者唯一索引将表
- Transaction And Lock--唯一索引下INSERT导致的死锁
- mysql隐式转换造成索引失效的事故总结
- HBase建表高级属性,hbase应用案例看行键设计,HBase和mapreduce结合,从Hbase中读取数据、分析,写入hdfs,从hdfs中读取数据写入Hbase,协处理器和二级索引
- 一次innodb自增主键与索引列null或者not null重要性案例
- 面试知识点6:MySQL中InnoDB的一级索引、二级索引
- 对于唯一索引使用唯一条件搜索, InnoDB 只锁定找到的index record,不是它之前的区间
- innodb purge--二级索引
- 关于MySQL InnoDB表的二级索引是否加入主键列的问题解释
- 测试索引访问途径(number与varchar2的隐式转换)
- 框架 day34 Hibernate,h对事务并发处理,管理session,二级缓存,h练习案例
- 隐式转换导致索引失效