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(读写锁). ...
随机推荐
- Systemtap kernel.trace("*") events source code
http://blog.163.com/digoal@126/blog/static/16387704020131014562216/
- iOS NavigaitonController详解(code版)
参考文章:http://blog.csdn.net/totogo2010/article/details/7681879,参考了这篇文章,写的超级好,自己他的基础上加上了自己的理解. 下面的图显示了导 ...
- 自定义控件(视图)2期笔记10:自定义视图之View事件分发机制("瀑布流"的案例)
1. Touch事件的传递: 图解Touch事件的传递,如下: 当我们点击子View 02内部的Button控件时候,我们就触发了Touch事件. • 这个Touch事件首先传递给了顶级父View ...
- Unity3D GUI学习
Unity3D内置有GUI, 首先,使用GUI实现一个按钮,并且点击实现触发, void OnGUI() { //GUI.Button (new Rect (10,10,50,50), "n ...
- object标签参考(转载)
<object> 元素可支持多种不同的媒介类型,比如: 图片 音频 视频 Other 对象 显示图片 你可以显示一幅图片: <object height="100%&quo ...
- Get file name without extension.
Ref:How to get file name without the extension? Normally,there are two ways to implements this:use t ...
- objectiv-c所有对象之间的交互是如何实现的?
在对象间交互中每个对象承担不同的角色,总的来说就是“数据发送者”和“数据接收者”两个角色.可以通过objective-c中给我们提供的手段来实现两者间的通讯.比如: “通知中心”NSNotificat ...
- iOS 集成支付宝遇到的问题(续)
调起支付宝进行支付时提示private key is null ,碰到这个问题有两种解决方案 第一种. 将私钥转成PKCS8替换一下原私钥即可 1.生成私钥pem, 执行命令openssl genr ...
- SGU 123.The sum
#include <iostream> using namespace std; int f[50]={0,1,1}; int main(){ int n,s=0; cin>> ...
- 虚拟机VHD格式解析到NTFS文件系统解析
本来的需求是XEN下的镜像取证,但这篇仅包括他支持的一种格式,就是VHD,此项目从头开始大概用了两周时间,中间遇到了很多让人头大的问题,光是思考的笔记就写了十几页纸,不过实际上并没有那么难,主要是很久 ...