锁的算法有三种,如下:

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. 大话listview之设置item监听器无效大坑之一:item设了属性clickable

    今天一个listview设置item监听器居然没有作用: 看了半天,怀疑是item设置了这个属性, 于是删了,果然就可以了. 大坑 ...

  2. jQuery封装和优化

    封装和优化插件 --封装插件 (function($){ //自定义插件代码 })(jQuery) --------------- (function($){ $.fn.extend({ //函数列表 ...

  3. (转)拉姆达表达式(Lambda Expressions) =>写法的涵义

      lambdaclass编译器 让我们先看一个简单的拉姆达表达式: x=>x/2 这个表达式的意思是:x为参数,对x进行相应的操作后的结果作为返回值. 通过这个拉姆达表达式,我们可以看到: 这 ...

  4. Python.tornado.2.tornado.options

    记录Tornado-4.0.2源码的阅读,学习,分析 options.py 1. imports 部分 1.1 __future__ from __future__ import absolute_i ...

  5. JS部分

    前端三剑客(HTML,CSS,JavaScript) Html:负责一个页面的结构 Css:负责一个页面的样式 JavaScript:负责与用户进行交互 JS概念 JS是JavaScript的简称,是 ...

  6. BZOJ2330或洛谷3275 [SCOI2011]糖果

    BZOJ原题链接 洛谷原题链接 很明显的差分约束,但数据范围较大,朴素\(SPFA\)判正环求解会\(T\)(理论上如此,但我看到有挺多人用朴素的还跑得挺快..),所以需要优化. 我们所建立的有向图中 ...

  7. NOIP需要掌握的内容(大致

    1.排序算法(快排.选择.冒泡.堆排序.二叉排序树.桶排序)2.DFS/BFS 剪枝 哈希表3.树   ①遍历   ②二叉树   ③二叉排序树(查找.生成.删除)   ④堆(二叉堆.左偏树.堆排序)  ...

  8. 秒懂 this

    一:全局执行 console.log(this); // Window 可以看出在全局作用域中 this 指向当前的全局对象 Window. 二:函数中执行 1.非严格模式中 function fun ...

  9. install virtualenv

    $ [sudo] pip install virtualenv $ mkdir ~/envs $ virtualenv ~/envs/lsbaws/ $ cd ~/envs/lsbaws/ $ ls ...

  10. 【搜索】 Prime Path

    #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include& ...