锁的算法有三种,如下:

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. php ActiveMQ的安装与使用

    一.ActiveMQ是什么?ActiveMQ是Apache出品,最流行的,能力强劲的开源消息总线.支持多种语言客户端(Java,C,C++,C#,Python,Ruby,Perl,PHP), 支持多种 ...

  2. JsRender 学习总结

    jsRender 三个最重要的概念:模板.容器和数据. 最重要的是:view(视图) 是我们定义的模板,上下文是视图所用的对象. 一.基础. {{:}} 和 {{>}}(或{{html:}})两 ...

  3. 【gRPC使用问题3】生成出来无法识别Google.Api.AnnotationsReflection.Descriptor

    1.问题截图: 2.解决方案: Install the package "Google.Api.Gax.Grpc". From the Package Manager Consol ...

  4. c#networkcomms protobuf-net 文件加载出现问题

    服务器端里添加客户管理添加了些功能, 客户端私活连不上了,老程序没问题, 在服务器端程序里边也接受不到事件,客户端就提示链接中断了, 在客户端里边查了 链接中断是客户端上做的,当传回的包为0 事,程序 ...

  5. NSIS Error:Error writing temporary file. Make sure your temp folder is valid的解决办法

    我的是Win7 32位,当前登录用户已经是管理员,在安装腾讯视频电脑版时,提示以上错误,无法安装. 查了好多资料,按如下方法解决了: 在win7下,以管理员的身份打开cmd(在window\syste ...

  6. andorid 表格布局

    tablelayout.xml表格布局 <?xml version="1.0" encoding="utf-8"?> <TableLayout ...

  7. poj 1321 (简单DFS) 棋盘问题

    题目:http://poj.org/problem?id=1321 最近状态有点down, 练练手 #include<cstdio> using namespace std; ][]; ] ...

  8. Architecture.SOLID-Principles

    SOLID Principles Reference 1. Single Responsibility http://en.wikipedia.org/wiki/Single_responsibili ...

  9. Selenium+PhantomJS

    Selenium Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同是Selenium 可以直接运行在浏览器上, ...

  10. html中 &nbsp; 和空格的区别

    Non-Breaking Space 注意是    这6个字符是一个整体, 在html中, 是空格的占位符.一个   代表一个空格:两个 代表两个空格,即使用几个 就显示几个空格. 但是普通的空格在h ...