Gap Locks 区间锁
Gap Locks 区间锁 1.
区间锁不能用于语句锁定记录使用一个唯一索引来搜索一个唯一的记录 2.READ COMMITTED 没有区间锁 区间锁是一个锁在一个在index记录间的区间,或者一个lock 在gap 在第一个前或者最后一个index recoed 之后, 比如,SELECT c1 FOR UPDATE FROM t WHERE c1 BETWEEN 10 and 20; 会阻止其他事务插入15的值到列t.c1, 无论这里已经有任何这样的值在列里, 因为区间在所有存在的值在范围内被锁定 区间可以跨越一个单个的index值,多个index值 甚至空的index值 区间锁是性能和并发的折中方案,并用于一些事务隔离级别 而不是其他 区间锁不能用于语句锁定记录使用一个唯一索引来搜索一个唯一的记录(这个不包含例子搜索条件只包含只是一个多列唯一索引的一部分列,在这种情况下,gap locking 仍旧存在) 例如,如果id列有一个唯一的索引,下面的语句使用一个index-record lock 用于记录id值100 它不管书是否其他sessin插入记录在之前的区间 SELECT * FROM child WHERE id = 100; 如果id没有索引或者有一个非唯一的索引,语句会lock前面的区间 它也是值得注意的 冲突的锁可以被持有一个区间通过不同的事务。 比如,事务A持有一个共享gap lock(gap S-lock) 在区间 当事务B持有一个排它的gap lock(gap X-lock) 在相同的区间。 冲突的gap locks 是被允许的 如果一个记录是从一个index被清除, gap locks 持有记录通过不同的事务必须被合并 区间锁在InnoDB 是"纯粹抑制的",这意味着只有停止其他事务插入这个区间。 它们不阻止不同事务来占据区间锁在相同的区间,因此,一个gap X-lock 有相同的影响作为一个gap S-lock Gap lock 可以显示的关闭,这个发生如果你改变了事务的隔离级别 为READ COMMITTED 或者让启用innodb_locks_unsafe_for_binlog 系统变量(现在是过时了) 区间锁示例: mysql> show create table SmsTest;
+--------- +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------+
| Table | Create Table |
+--------- +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------+
| SmsTest | CREATE TABLE `SmsTest` (
`sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号',
`phoneNo` varchar(16) NOT NULL DEFAULT '' COMMENT '电话号码',
`channelType` int(11) DEFAULT NULL COMMENT '通道识别',
`status` tinyint(4) NOT NULL COMMENT '短信转态,1.发送成功,2.发送失败,3.发送异常',
PRIMARY KEY (`sn`)
) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8 COMMENT='短信发送成功记录表' |
+--------- +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------+
1 row in set (0.00 sec) mysql> select min(sn),max(sn) from SmsTest;
+---------+---------+
| min(sn) | max(sn) |
+---------+---------+
| 1 | 200 |
+---------+---------+
1 row in set (0.00 sec) 测试1 更新列没有索引的情况下: Session 1: mysql> show create table SmsTest;
+--------- +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------+
| Table | Create Table |
+--------- +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------+
| SmsTest | CREATE TABLE `SmsTest` (
`sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号',
`phoneNo` int(16) NOT NULL ,
`channelType` int(11) DEFAULT NULL COMMENT '通道识别',
`status` tinyint(4) NOT NULL COMMENT '短信转态,1.发送成功,2.发送失败,3.发送异常',
PRIMARY KEY (`sn`)
) ENGINE=InnoDB AUTO_INCREMENT=45209 DEFAULT CHARSET=utf8 COMMENT='短信发送成功记录表' |
+--------- +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------+
1 row in set (0.00 sec) mysql> insert into SmsTest select sn,sn,channelType,status from SmsRecord limit 200;
Query OK, 200 rows affected (0.09 sec)
Records: 200 Duplicates: 0 Warnings: 0 mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) mysql> update SmsTest set phoneNo=111 where phoneNo=1;
Query OK, 0 rows affected (0.04 sec)
Rows matched: 0 Changed: 0 Warnings: 0 mysql> explain update SmsTest set phoneNo=111 where phoneNo=1;
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | SmsTest | index | NULL | PRIMARY | 4 | NULL | 200 | Using where |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.01 sec) Session 2: mysql> insert into SmsTest values(201,1,1,1); ---插入Hang mysql> delete from SmsTest where sn=99; ---删除Hang 验证了 如果RR隔离,更新列没有索引,会锁全表 测试2 在更新列上加上索引: mysql> create index SmsTest_idx1 on SmsTest(phoneNo);
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql>
mysql>
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) mysql> update SmsTest set phoneNo=111 where phoneNo=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> explain update SmsTest set phoneNo=111 where phoneNo=1;
+----+-------------+---------+-------+---------------+--------------+---------+-------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+--------------+---------+-------+------+------------------------------+
| 1 | SIMPLE | SmsTest | range | SmsTest_idx1 | SmsTest_idx1 | 4 | const | 1 | Using where; Using temporary |
+----+-------------+---------+-------+---------------+--------------+---------+-------+------+------------------------------+
1 row in set (0.00 sec)-+-------+---------------+--------------+---------+-------+------+------------------------------+
1 row in set (0.00 sec) Session 2:
mysql> insert into SmsTest values(201,1,1,1); --hang mysql> insert into SmsTest values(201,2,1,1);
Query OK, 1 row affected (0.00 sec) mysql> insert into SmsTest values(201,3,1,1);
ERROR 1062 (23000): Duplicate entry '201' for key 'PRIMARY'
mysql> insert into SmsTest values(3,1,1);
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into SmsTest(PhoneNo,channelType,status) values(3,1,1);
Query OK, 1 row affected (0.01 sec) mysql> insert into SmsTest(PhoneNo,channelType,status) values(1,1,1); --hang 此时插入PhoneNo=1会hang 测试区间锁: Session 1: mysql> start transaction;
Query OK, 0 rows affected (0.00 sec) mysql> update SmsTest set phoneNo=111 where phoneNo between 10 and 20;
Query OK, 11 rows affected (0.00 sec)
Rows matched: 11 Changed: 11 Warnings: 0 mysql> explain update SmsTest set phoneNo=111 where phoneNo between 10 and 20;
+----+-------------+---------+-------+---------------+--------------+---------+-------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+--------------+---------+-------+------+------------------------------+
| 1 | SIMPLE | SmsTest | range | SmsTest_idx1 | SmsTest_idx1 | 4 | const | 11 | Using where; Using temporary |
+----+-------------+---------+-------+---------------+--------------+---------+-------+------+------------------------------+
1 row in set (0.00 sec) 锁住11行 Session 2: mysql> insert into SmsTest(PhoneNo,channelType,status) values(1,1,1);
Query OK, 1 row affected (0.01 sec) mysql> insert into SmsTest(PhoneNo,channelType,status) values(2,1,1);
Query OK, 1 row affected (0.00 sec) mysql> insert into SmsTest(PhoneNo,channelType,status) values(3,1,1);
Query OK, 1 row affected (0.00 sec) mysql> insert into SmsTest(PhoneNo,channelType,status) values(4,1,1);
Query OK, 1 row affected (0.00 sec) mysql> insert into SmsTest(PhoneNo,channelType,status) values(5,1,1);
Query OK, 1 row affected (0.00 sec) mysql> insert into SmsTest(PhoneNo,channelType,status) values(6,1,1);
Query OK, 1 row affected (0.00 sec) mysql> insert into SmsTest(PhoneNo,channelType,status) values(7,1,1);
Query OK, 1 row affected (0.01 sec) mysql> insert into SmsTest(PhoneNo,channelType,status) values(8,1,1);
Query OK, 1 row affected (0.00 sec) mysql> insert into SmsTest(PhoneNo,channelType,status) values(9,1,1); --hang mysql> insert into SmsTest(PhoneNo,channelType,status) values(10,1,1); --hang mysql> insert into SmsTest(PhoneNo,channelType,status) values(11,1,1);--hang mysql> insert into SmsTest(PhoneNo,channelType,status) values(12,1,1); --hang mysql> insert into SmsTest(PhoneNo,channelType,status) values(13,1,1); --hang mysql> insert into SmsTest(PhoneNo,channelType,status) values(14,1,1); --hang mysql> insert into zjzc.SmsTest(PhoneNo,channelType,status) values(15,1,1); --hang mysql> insert into zjzc.SmsTest(PhoneNo,channelType,status) values(16,1,1); --hang mysql> insert into zjzc.SmsTest(PhoneNo,channelType,status) values(17,1,1);--hang mysql> insert into zjzc.SmsTest(PhoneNo,channelType,status) values(19,1,1); --hang mysql> insert into zjzc.SmsTest(PhoneNo,channelType,status) values(20,1,1); --hang mysql> insert into zjzc.SmsTest(PhoneNo,channelType,status) values(21,1,1);
Query OK, 1 row affected (0.03 sec) mysql> insert into zjzc.SmsTest(PhoneNo,channelType,status) values(22,1,1);
Query OK, 1 row affected (0.00 sec) mysql> insert into zjzc.SmsTest(PhoneNo,channelType,status) values(23,1,1);
Query OK, 1 row affected (0.00 sec)
Gap Locks 区间锁的更多相关文章
- RR区间锁 不是唯一索引,即使区间内没值,也锁
+--------- +---------------------------------------------------------------------------------------- ...
- RR模式下利用区间锁防止幻读,RC模式没有区间锁会出现幻读
Session 1: mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from ...
- mysql 区间锁 对于没有索引 非唯一索引 唯一索引 各种情况
The locks are normally next-key locks that also block inserts into the "gap" immediately b ...
- Gap 锁
14.3.1 InnoDB Locking InnoDB 锁 本章节描述InnoDB 使用的锁类型: Shared and Exclusive Locks Intention Locks Record ...
- mysql insert锁机制【转】
最近再找一些MySQL锁表原因,整理出来一部分sql语句会锁表的,方便查阅,整理的不是很全,都是工作中碰到的,会持续更新 笔者能力有限,如果有不正确的,或者不到位的地方,还请大家指出来,方便你我,方便 ...
- InnoDB的锁机制浅析(二)—探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意向锁)
Record锁/Gap锁/Next-key锁/插入意向锁 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Recor ...
- autocommit 隔离级别 next lock gap lock 事务隔离级别和锁
autocommit 隔离级别 https://www.ibm.com/developerworks/cn/opensource/os-mysql-transaction-isolation-leve ...
- InnoDB锁机制
1. 锁类型 锁是数据库区别与文件系统的一个关键特性,锁机制用于管理对共享资源的并发访问. InnoDB使用的锁类型,分别有: 共享锁(S)和排他锁(X) 意向锁(IS和IX) 自增长锁(AUTO-I ...
- innoDB锁小结
innodb的锁分两类:lock和latch. 其中latch主要是保证并发线程操作临界资源的正确性,要求时间非常短,所以没有死锁检测机制.latch包括mutex(互斥量)和rwlock(读写锁). ...
随机推荐
- Java基础知识强化之集合框架笔记28:ArrayList集合练习之去除ArrayList集合中的重复字符串元素(升级)
1. 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同) 要求:不能创建新的集合,就在以前的集合上做. 2. 代码示例之 去除集合中重复元素,不创建新的集合: package ...
- mac 下svn降级
mac 手欠 homebrew 安装完成后 brew install svn svn版本更新至1.8.11 公司svn 不支持1.8 需要降级 搜索很多资料 写的比较麻烦 总结出来是先卸载再 ...
- linux系统下安装wget。
我们先安装linux系统比如centos7.1里面有的就没有wget下载工具.wget这个命令就不可以使用. 我们使用 yum -y install wget yum install perl 会出现 ...
- 使用WebSocket构建实时WEB
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3795075.html ...
- 织梦dede编辑器ckeditor如何添加中文字体不乱码
dedecms内容编辑器ckeditor没有中文字体,找了很多教程都是千篇一律,而且都是错的,终于找到了一篇,结合自己的实际操作,来教您如何添加中文字体,并且解决乱码问题. 工具/原料 dedec ...
- node基础再现--module.exports 和exports
实际上,最最基础的方法,最最原始的方法是module.exports,至于exports,是为了方便书写才出来的,应该说,module.exports 包含exports,所工作的范围更加的广泛! m ...
- 脚本动态监控input
Jquery $('input').bind('input propertychange', function() { //进行相关操作 }); JS if(isIE) { document.getE ...
- 监听polygon变化
Polygons are made of Paths which are just MVCArrays (in this case, they're a list of LatLng objects) ...
- openwrt advanced configuration
openwrt高级配置(汗 照着标题就翻译过来了) openwrt Kamikaze 8.09的一般配置文件都在目录 /etc/config 下面,可以使用脚本来调用参数和设置参数. 比如 sbin/ ...
- OC - 24.CABasicAnimation
概述 简介 CABasicAnimation是抽象类CAPropertyAnimation的子类,可以直接使用 CABasicAnimation又称基本动画,从fromValue到toValue按照指 ...