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(读写锁). ...
随机推荐
- mysql使用硬链接配合truncate 删除2.2T的表 --杨奇龙
http://blog.csdn.net/wyzxg/article/details/8626814 http://blog.itpub.net/22664653/viewspace-750408/ ...
- 删除右键菜单的“用阿里旺旺发送此文件”项
在运行对话框里的输入框内输入Regedit.exe,点击确定按钮就启动了注册表编辑器程序. 在注册表编辑器窗口左侧展开HKEY_CLASSES_ROOT\CLSID{0DE1378D-F811-40E ...
- Java基础知识强化09:String、StringBuffer和StringBuilder使用
1. 对于三者使用的总结: (1).如果要操作少量的数据用 = String (2).单线程操作字符串缓冲区下操作大量数据 = StringBuilder (3).多线程操 ...
- (转)if语句优化
一.使用常见的三元操作符 if (foo) bar(); else baz(); ==> foo?bar():baz(); if (!foo) bar(); else baz(); ==> ...
- 使用Convert 类和Parse方法将字符串转换为数值类型
//用Parse方法将字符串转换为数值类型; long num=Int64.Parse(args[2]) //用别名为Int64c#类型long; long num=long.Parse(args[2 ...
- SSL VPN 详解
SSL VPN是专栏VPN系列技术原理的最后一篇,SSL VPN作为远程接入型的VPN,已经具备非常广阔的前景,它的主要适应场景是取代L2TP Over IPSec,但功能要比L2TP Over IP ...
- CI框架多目录设置
1,设置目的,前台与后台实现独立目录管理 2.通过http://www.myci.com 访问前台,通过http://www.myci.com/admin 访问后台, 多目录的意思是指在同一个网 ...
- 主成份分析PCA
Data Mining 主成分分析PCA 降维的必要性 1.多重共线性--预测变量之间相互关联.多重共线性会导致解空间的不稳定,从而可能导致结果的不连贯. 2.高维空间本身具有稀疏性.一维正态分布有6 ...
- HDU 4010.Query on The Trees 解题报告
题意: 给出一颗树,有4种操作: 1.如果x和y不在同一棵树上则在xy连边 2.如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离 3.如果x和y在同一棵树上则x到y的路径上所有的点 ...
- POJ 3468.A Simple Problem with Integers 解题报告
用树状数组和线段树会比较简单,这里用这道题来学习Splay. 第一次写,代码比较丑 /* 初始化添加一个key值足够大的结点 保证每个需要的结点都有后继 */ #include <iostrea ...