锁的算法有三种,如下:

record lock、gap lock、next_key lock

在不同的隔离级别下,所使用的锁的算法如下:

RC:仅有record 锁

RR:有record和next_key锁

行锁都是基于索引来实现的

现在我们就来讨论在RR模式下,各种SQL语句的锁的记录范围:

create table t1(
id int primary key auto_increment,
col1 int not null default 0,
col2 varchar(20) not null default '',
col3 datetime not null default '2010-01-01 00:00:00',
unique key(col1),
key(col2));

首先写个生产测试数据的存储过程:

delimiter $$
create procedure proc_generate_data(in i_rec_num int,in i_prefix_name varchar(),in i_is_order tinyint)
begin
declare rec_num int;
declare prefix_name varchar();
declare is_order tinyint;
declare i int;
set i=;
set rec_num=i_rec_num;
set prefix_name=i_prefix_name;
set is_order=i_is_order;
loop1:while (i<rec_num) do
set @c1=floor(round(rand(),)*);
set @c2=concat(prefix_name,@c1);
set @c3=now();
if is_order = then
insert into t1(col1,col2,col3)values(@c1,@c2,@c3);
elseif is_order = then
set @id= floor(round(rand(),)*);
select into @if_exist from t1 where id=@id;
if @if_exist != then
insert into t1(id,col1,col2,col3)values(@id,@c1,@c2,@c3);
else
insert into t1(col1,col2,col3)values(@c1,@c2,@c3);
end if;
else
insert into t1(col1,col2,col3)values(,'nihao',@c3);
end if;
set i= i+;
end while loop1;
end $$
delimiter ;

生成测试数据:

顺序生成: call proc_generate_data(10000,'first',0);

随机生成: call proc_generate_data(10000,'second',1);

mysql> select count(*) from t1;
+----------+
| count(*) |
+----------+
| |
+----------+
row in set (0.00 sec)
alter table t1 rename t1_1;
create table t1 like t1_1;

测试说明:

间隙锁定的表现是:间隙允许update不允许insert

类目   常见句式 结论
主键|唯一索引

update t1 set col2='OK' where id=1001;
update t1 set col2='OK' where col1=9800;

1.若对应的id值存在,锁定primary key& unique key对应的record;
若DML最终涉及了primary key& unique key对应的record,还是会被堵塞;
DML走的是全表扫描,会被堵塞;
2.若对应的id值不存在,对primary key&unique key对应的record允许update不允许insert;

update t1 set  col2='OK' where id<1001; 锁住where范围内的primary key&unique key对应的record
普通索引 update t1 set col2='OK' where  col2='first1234';

1.若对应的col2 record存在,对(col2_last_value,col2_value)及(col2_value,col2_next_value)产生间隙锁定;并对col2_value产生record锁定;
2.若对应的col2 record不存在,对(col2_last_value,col2_next_value)产生间隙锁定;

update t1 set col2='OK' where  col2>'first1234'; 对(负无穷大,col2_value)产生间隙锁定,并对范围内的行的主键进行record锁定;
无索引 update t1 set col2='ERROR' where col3<'2017-09-30 10:00:00'; 锁全表;
INSERT

insert into t1 values(650,650,'six650','2017-09-30 15:10:00');
insert into t1 values(),(),(),(),();

锁住primary key& unique key对应的record

insert into t1 select * from t1_1;

1.事务期间,锁定操作主键,唯一索引对应的record、间隙及以外的部分内容;
2.事务期间,锁定操作主键,唯一索引对应的间隙(间隙锁定)

总结:

1.  主键索引有record lock

2.  唯一辅助索引有record lock

3.  非唯一辅助索引有next-key lock

4.  没有索引的话,则是全表范围的next-key lock

5.  RC下只有record lock

6.  RR&innodb_locks_unsafe_for_binlog=1,只有record lock.

MySQL RR模式下如何加锁的更多相关文章

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

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

  2. RR模式下的事务隔离

    <pre name="code" class="html">mysql> select * from t100; Session 2: +-- ...

  3. mysql主从模式下在主库上的某些操作不记录日志的方法

    mysql主从模式下在主库上的某些操作不记录日志的方法 需求场景: 在主库上的需要删除某个用户,而这个用户在从库上不存在(我在接手一个业务的时候,就遇到主从架构用户授权不一致的情况,主库比较全,而从库 ...

  4. mysql READ-COMMITTED 模式下 行锁不会升级到表级锁

    mysql> select sn,id,info from s100 group by id; +-----+------+------+ | sn | id | info | +-----+- ...

  5. MySQL Binlog--MIXED模式下数据更新

    在 Mixed 模式下,MySQL 会根据执行的每一条具体的 SQL 语句来区分对待记录的日志形式,也就是在 statement 和 row 之间选择一种.如果SQL语句为UPDATE/DELETE等 ...

  6. SELECT ... LOCK IN SHARE MODE和SELECT ... FOR UPDATE locks在RR模式下可以看到最新的记录

    14.5.2.4 Locking Reads 锁定读: 如果你查询数据然后插入或者修改相关数据在相同的事务里, 常规的SELECT 语句不能给予足够的保护. 其他事务可以修改或者删除你刚查询相同的记录 ...

  7. MySQL RR隔离 读一致性

    MySQL RR 模式下 事务隔离问题: Session 1: mysql> select * from test; +------+------+ | id | name | +------+ ...

  8. 在不重启MySQL的情况下用gdb工具设置变量

    前提:此方法只是参考其它博客的一个记录,未经亲自验证 当在mysql客户端设置一些变量时提示如下报错: 于是想能否有办法在不重启的情况下设置这些只读变量,在网上搜索别人的博客后发现如下方法 1.命令行 ...

  9. mysql RR下不存在则插入

    主要看并发事务中不存在则插入(只有key索引)的阻塞情况. 表定义: mysql> desc user; +-------------+------------------+------+--- ...

随机推荐

  1. cmd乱码问题

    1.进入 cmd 窗口 2.字符编码切换回中文:chcp 936 MS-DOS为以下国家和语言提供字符集:  代码页描述  1258 越南语  1257 波罗的语  1256 阿拉伯语  1255 希 ...

  2. (四)创建ROS程序包(就是软件包)

    你的 ROS 程序包都放到下面这个目录里, 切换到这个目录: $ cd ~/catkin_ws/src 使用下面的命令: 创建一个 ROS 程序包 名字就叫:beginner_tutorials $ ...

  3. golang语言中os/signal包的学习与使用

    package main; import ( "os" "os/signal" "fmt" ) //signal包中提供了两个函数 //No ...

  4. SQL删除重复数据只保留一条数据

    1.表结构与数据: CREATE TABLE tablezzl( id int, name ) ); 2.查询出重复的数据: 3.查询出要保留的重复数据: 4.最终的SQL: DELETE FROM ...

  5. springboot 项目添加jaeger调用链监控

    1.添加maven依赖<dependency> <groupId>io.opentracing.contrib</groupId> <artifactId&g ...

  6. PopupWindow与Edittext结合使用所遇到的坑

    PopupWindow与Edittext结合使用一起实现目的:既可以编辑输入想要的内容,还可以通过下拉列表来实现内容的选择. 我就是这样的一个目的,结果很简单的目的却遇到了很大的坑,下面我将把我遇到的 ...

  7. PAT 1029 旧键盘(20)(代码)

    1029 旧键盘(20)(20 分) 旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及实际被输入的文字,请你列出肯定坏掉的那些键. 输入格式: 输入在 ...

  8. JVM 堆参数调优 (四)

    堆参数调优 1.堆的结构 JAVA7 堆逻辑上分为:新生区.养老区.永久区:实际上堆只有新生区.养老区: Minor GC:轻量的垃圾回收:   Major GC(Full GC):重量级垃圾回收. ...

  9. CSS中(font和background)的简写形式

    转自:http://blog.csdn.net/shenzhennba/article/details/7356095 1.字体属性主要包括下面几个:font-family(字体族): “Arial” ...

  10. GitHub上README.md教程 详情介绍 (修改图片连接地址错误)

    最近对它的README.md文件颇为感兴趣.便写下这贴,帮助更多的还不会编写README文件的同学们. README文件后缀名为md.md是markdown的缩写,markdown是一种编辑博客的语言 ...