锁的算法有三种,如下:

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. 7-OKHttp使用详解,步骤挺详细的,适合初学者使用!

    OKHttp使用详解,步骤挺详细的,适合初学者使用! 一,OKHttp介绍 okhttp是一个第三方类库,用于android中请求网络. 这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Squ ...

  2. migrantion

    Enable-Migrations - ConfigurationTypeName namespace.DbContext Enable-Migrations命令创建了一个新的Migrations文件 ...

  3. [z]根据awr报告查看最慢的sql语句

    http://blog.itpub.net/12679300/viewspace-2125679/ 当系统运行了一段时间后,系统基本也趋于稳定了,SQL调优也变了DBA的一个主要的工作内容,很多时候都 ...

  4. IIS站点报拒绝访问Temporary ASP.NET Files的解决办法

    IIS站点本来运行的好好的,突然就出现了:Temporary ASP.NET Files拒绝访问的问题.遇到此类问题,请逐步排查,定可解决. 原因:Windows操作系统升级导致. 办法: 1.检查C ...

  5. Oracle_SQL(1) 基本查询

    1.oracle的安装与卸载 2.PL/SQL Developer的安装 3.登陆PL/SQL Developer 4.SCOTT用户下表的介绍 5.基本查询语句 查询雇员的所有信息: select ...

  6. BFS和DFS (java版)

    package com.algorithm.test; import java.util.ArrayDeque; import java.util.Scanner; public class DfsA ...

  7. XiaoKL学Python(D)argparse

    该文以Python 2为基础. 1. argparse简介 argparse使得编写用户友好的命令行接口更简单. argparse知道如何解析sys.argv. argparse 模块自动生成 “帮助 ...

  8. CH6802 車的放置

    原题链接 和棋盘覆盖(题解)差不多. 将行和列看成\(n+m\)个节点,且分属两个集合,如果某个节点没有被禁止,则行坐标对应节点向列坐标对应节点连边,然后就是求二分图最大匹配了. #include&l ...

  9. jdk8 tomcat7

    今天想使用jdk8+tomcat7来个写程序,但是一运行始终提示连接不到数据库 提示:Could not obtain connection metadata org.apache.tomcat.db ...

  10. jquery动态出操作select

    var citys = {1:'北京',2:'上海',3:'广州',4:'深圳'}; $("#city option:gt(0)").remove(); for(var k in ...