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 区间锁的更多相关文章

  1. RR区间锁 不是唯一索引,即使区间内没值,也锁

    +--------- +---------------------------------------------------------------------------------------- ...

  2. RR模式下利用区间锁防止幻读,RC模式没有区间锁会出现幻读

    Session 1: mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from ...

  3. mysql 区间锁 对于没有索引 非唯一索引 唯一索引 各种情况

    The locks are normally next-key locks that also block inserts into the "gap" immediately b ...

  4. Gap 锁

    14.3.1 InnoDB Locking InnoDB 锁 本章节描述InnoDB 使用的锁类型: Shared and Exclusive Locks Intention Locks Record ...

  5. mysql insert锁机制【转】

    最近再找一些MySQL锁表原因,整理出来一部分sql语句会锁表的,方便查阅,整理的不是很全,都是工作中碰到的,会持续更新 笔者能力有限,如果有不正确的,或者不到位的地方,还请大家指出来,方便你我,方便 ...

  6. InnoDB的锁机制浅析(二)—探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意向锁)

    Record锁/Gap锁/Next-key锁/插入意向锁 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Recor ...

  7. autocommit 隔离级别 next lock gap lock 事务隔离级别和锁

    autocommit 隔离级别 https://www.ibm.com/developerworks/cn/opensource/os-mysql-transaction-isolation-leve ...

  8. InnoDB锁机制

    1. 锁类型 锁是数据库区别与文件系统的一个关键特性,锁机制用于管理对共享资源的并发访问. InnoDB使用的锁类型,分别有: 共享锁(S)和排他锁(X) 意向锁(IS和IX) 自增长锁(AUTO-I ...

  9. innoDB锁小结

    innodb的锁分两类:lock和latch. 其中latch主要是保证并发线程操作临界资源的正确性,要求时间非常短,所以没有死锁检测机制.latch包括mutex(互斥量)和rwlock(读写锁). ...

随机推荐

  1. C#开发学习——内联表达式

    <%@ 表示:引用 <%# 表示:绑定 <%= 表示:取值     <%= 变量名%> Response.Write()输出和<%=%>输出最后的效果是一样的 ...

  2. IIS7.5 asp+access数据库连接失败处理 64位系统

    IIS7.5 asp+access数据库连接失败处理(SRV 2008R2 x64/win7 x64) IIS7.5不支持oledb4.0驱动?把IIS运行模式设置成32位就可以了,微软没有支持出64 ...

  3. 设置ORACLE环境变量

    sqlplus 执行不了可能原因是未设置环境变量,设置方法:  export ORACLE_HOME=/usr/local/instantclient_11_2

  4. Deep Learning 学习随记(八)CNN(Convolutional neural network)理解

    前面Andrew Ng的讲义基本看完了.Andrew讲的真是通俗易懂,只是不过瘾啊,讲的太少了.趁着看完那章convolution and pooling, 自己又去翻了翻CNN的相关东西. 当时看讲 ...

  5. winform降低功耗总结

    这里整理了一些网上关于Winform如何降低系统内存占用的资料,供参考: 1.使用性能测试工具dotTrace 3.0,它能够计算出你程序中那些代码占用内存较多2.强制垃圾回收3.多dispose,c ...

  6. C# 多线程详解

    1.使用多线程的几种方式 (1)不需要传递参数,也不需要返回参数 ThreadStart是一个委托,这个委托的定义为void ThreadStart(),没有参数与返回值. 复制代码 代码如下: cl ...

  7. SGU 128.Snake

    时间限制:0.25s 空间限制:4m 题意: 在一个平面坐标中有N个点,现在要你用这N个点构造一个闭合图形,这个图形要满足以下条件: 1.这个图形要是闭合的:          2.图形上的点只能是给 ...

  8. 『重构--改善既有代码的设计』读书笔记----Remove Middle Man

    如果你发现某个类做了过多的简单委托动作,你就可以考虑是否可以让客户直接去调用受托类.在Hide Delegate中,我们介绍了封装受托对象的好处,但好处归好处也存在代价,就是当你每次需要在受托对象中增 ...

  9. 《作业控制系列》-“linux命令五分钟系列”之十

    本原创文章属于<Linux大棚>博客. 博客地址为http://roclinux.cn. 文章作者为roc 希望您能通过捐款的方式支持Linux大棚博客的运行和发展.请见“关于捐款” == ...

  10. Fedora 21 安装Infinality

    原文地址: Fedora 21 用infinality美化你的字体 http://blog.csdn.net/element207/article/details/41746683 安装infinal ...