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 的 read_buffer_size 参数是如何影响写缓冲和写性能的?
Each thread // that does a sequential scan . The value of this variable should be a multiple of 4KB. ...
- 使用AVCaptureSession显示相机预览
#import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @interface ViewController ...
- xslt语法之---position()函数
最近在学习使用XSLT,很好很强大的样式表语言.使用到了position()函数特此记录一下. position()函数--返回节点位置 语法:position() 参数:无 返回值:整数 用途:该函 ...
- Java基础知识强化07:打印出空心菱形
1.如图打印出空心菱形: 2.下面是逻辑实现代码: package himi.hebao04; import java.util.Scanner; public class TestDemo08 { ...
- linux下vi命令笔记
vim 编辑器 全屏编辑器 模式化编辑器 vi:Visual Interfacevim:VI iMproved vi增强版vi模式: 编辑模式(命令模式)(默认处于编辑模式) Ct ...
- vs2013下的WCFRest 模板开发WCF
在vs2013下使用wcfRestservice40 是安装不成功的,尝试多遍,都是这样.查看以前vs2012做的wcfrest,经过调教,终于在vs2013下也可以了! 1.新建wcf服务应用程序 ...
- Tomcat-java.lang.IllegalArgumentException: Document base F:apps does not exist or is not a readable
启动Tomcat的时候,报错:java.lang.IllegalArgumentException: Document base F:apps does not exist or is not a r ...
- method=“post/get”
Form表单中method="post/get'的区别 Form提供了两种数据传输的方式——get和post.虽然它们都是数据的提交方式,但是在实际传输时确有很大的不同,并且可能会对数据 ...
- 比较两份文件的异同-beyond compare
比较两份文件的异同-beyond compare 今天又学到一个知识,比较两次文件的 异同. 哈哈 谢谢领导
- hdoj 2047 简单递推
代码: #include <stdio.h>int main(){ int n,m,i; __int64 x[41]; x[1]=3; x[2]=8; for(i=3;i<=40;i ...