数据库的锁

关于mysql有哪些锁?锁的分类有哪些?可查看另外一篇博客:mysql 的锁

下面主要是记录在实际情景中的加锁情况进行分析

测试环境介绍

innodb 引擎下,隔离级别在 REPEATABLE READ 进行测试

表结构介绍

(1)简单的测试表一:study表,id为主键

create table study(id int  primary key,name varchar(255),age int) engine=innodb;
insert study values(7 , 'g' , 21);

(2)简单的测试表二:study表,id为主键

create table my_table(
id int  primary key,
year int
) engine=innodb;
insert into my_table values(1, 2000),(2,2005),(3,2007),(4,2010),(5,2012),(6,2017);

隔离级别的介绍

1、数据库的隔离级别:

能”表示能解决,“否”表示不能解决。

脏读 不可重复读 幻读
未提交读
提交读
可重复读
串行读

2、查询数据库的隔离级别

SELECT @@tx_isolation

3、修改数据库隔离级别:

SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ| SERIALIZABLE}

  • 隔离级别名称可选值:READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ,SERIALIZABLE
  • global:设置全局session,但当前session不受影响。
  • session,设置当前和之后的所有session。
  • 都不写:设置当前session下一个还未开始的事务。

4、本测试环境使用的隔离级别

加锁情况介绍

具体查看这篇博客,这里大概还是列举一下锁有哪些:

mysql 的锁

注意:MyISAM引擎,如果需要进行锁表的操作,必须用lock table来进行,delete、update,insert语句会自动锁整个表

下面是对innodb引擎的锁类型进行介绍:

1、锁分类介绍:

(1)从锁的范围来分

  • 行锁:记录锁、间隙锁、next-key 锁
  • 表锁

(2)从对资源访问是否加锁来分:

  • 乐观锁:不对资源加锁,只有在更新的时候才会判断数据会不会被修改,如果被修改,则修改失败
  • 悲观锁:访问的时候就对资源加锁,加锁后别的访问不允许对其进行更新/删除操作

(3)从对数据的访问形式来分

  • 读锁:共享读
  • 写锁:独享写

2、加锁具体的实现方式

(1)默认的加锁及其对应加锁的类型

  • 普通的select(没有加lock in share mode或for update)不会锁表或锁行的
  • 常见的增删改(INSERT、DELETE、UPDATE)语句会自动对操作的数据行加写锁,其他对该数据进行操作的时候需要等待该事务提交后

(2)显式的加锁

  • select xxxxx lock in share mode :加的是共享读锁,不会影响其他事务的读(这里指不加锁的读,可以再次加共享读锁,读上加写锁会失败),但会影响其他事务的写
  • select xxxx for update : 加的是写锁,不加锁的读不会被影响,任意加锁的读会受影响,其他事务的写也会受影响

(3)举例:(在study表上进行测试)

举例一:测试共享读(lock in share mode)

事务一:

开启一个事务,对 id 为 7的加一个共享读锁(lock in share mode),不提交事务

事务二:

第一次尝试:开启一个事务,对 id 为 7的进行更新(会尝试获取到锁),操作不成功

第二次尝试:开启一个事务,也对 id 为 7的进行查询(不加锁的查询),操作成功

第三次尝试:开启一个事务,也对 id 为 7的进行查询(加共享读锁的查询),操作成功

第四次尝试:开启一个事务,也对 id 为 7的进行查询(加独享写锁的查询),操作失败

举例二:测试写锁(for update)

事务一:

开启一个事务,对 id 为 7的加一个写锁(for update),不提交事务

事务二:

第一次尝试:开启一个事务,对 id 为 7的进行更新(会尝试获取到锁),操作不成功

第二次尝试:开启一个事务,也对 id 为 7的进行查询(不加锁的查询),操作成功

第三次尝试:开启一个事务,也对 id 为 7的进行查询(加共享读锁的查询),操作失败(加写锁的读同理,也不会操作成功)

不同索引下的加锁问题

判断加不同的行锁时候加锁的类型是啥

(1)主键索引

上面举例介绍得到的一些总结,当id为主键的时候 对study 表的一些sql的加锁情况:

1. select * from study where id = 7; # 快照读,对其他的读和写没有影响
2. select * from study where id = 7 lock in share mode; # 加共享读锁,不影响其他的加共享读,但是影响加任意形式的写锁
3. select * from study where id = 7 for update; # 加写锁,影响加任意形式的读或者写锁

(2)非唯一索引

基于my_table这个表进行测试,目前的数据大小范围是**[2000 , 2017]**

第一个事务:

在year字段上加上一个普通的索引,然后进行between查询

create index idx on my_table(year);
start transaction;
select * from my_table where year between 2007 and 2010 for update;

第二个事务:

start transaction;
insert into my_table values(10 , 2004); =>Query OK,
delete from my_table where year=2005; =>Query OK,
insert into my_table values(11 ,2005); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(11, 2006); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(11, 2007); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(11, 2008); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(11, 2010); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(11, 2011); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
delete from my_table where year=2012; => ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(11, 2012); =>Query OK,

加锁分析:

(1)加锁范围:(2005,2012], 也就是在2007,2010,2012上各加了一个Next key lock(记录锁+间隙锁)

(3)非唯一索引,唯一查询

事务一:

开启事务,查询2010这条记录,目前这个记录是唯一的一条数据

start transaction;
select * from my_table where year =2010 for update;

事务一:

delete from my_table where year=2007 => Query OK
insert into my_table values(12 ,2007); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(12 , 2009); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into my_table values(12 ,2010); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into my_table values(12 ,2011); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> delete from my_table where year=2012; => Query OK

加锁分析:

(1)加锁范围:(2007,2012), 在2010上加了一记录 锁,在2007-2010,2010-2012上加了一个间隙锁

(4)唯一索引,唯一查询

创建唯一索引

drop index idx on my_table;
create unique index idx on my_table(year);

事务一:

开启事务,查询2010这条记录,目前这个记录是唯一的一条数据,year也是唯一索引

start transaction;
select * from my_table where year =2010 for update;

事务二

insert into my_table values(13, 2009); =>Query OK
insert into my_table values(14, 2010); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(15 ,2011); =>Query OK

加锁分析:只在2010上加了一个行锁(record锁)

(5)唯一索引,不唯一查询

事务一:

开启事务,between查询

start transaction;
select * from my_table where year between 2007 and 2010 for update;

事务二:

delete from my_table where year=2005; => Query OK
insert into my_table values(15, 2006); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(15, 2007); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(15, 2008); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(15, 2010); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(15, 2011); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(15, 2012); =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
delete from my_table where year=2012; =>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
insert into my_table values(15,2013); =>Query OK

加锁分析:

(1)加锁范围:(2005,2012], 也就是在2007,2010,2012上各加了一个Next key lock(记录锁+间隙锁),与非唯一索引between查询情况一致

(6)总结

a、只有字段是唯一索引且只有一条记录的情况下,不用加Gap锁,其他情况都要加Gap锁。

b、间隙Gap锁锁定的区域:根据检索条件向左寻找最靠近检索条件的记录值A,作为左区间,向右寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B)。

c、如果不加索引进行加锁的扫描,那就是全表扫描,直接就是加上表锁。不涉及到更细粒度的行锁了

数据库锁与加锁情况介绍(记录锁、间隙锁、next-key锁)相关推荐

  1. MySQL数据库基础到进阶笔记整理包含事务、SQL优化、锁等内容

    写在前面 本文是在学习MySQL数据库时整理的笔记,可供初学者学习 是在https://dhc.pythonanywhere.com/entry/share/?key=12e4a7324f68371d ...

  2. mysql数据 锁 隔离级别_MySQL数据库事务各隔离级别加锁情况--read uncommitted篇

    1.目的 1.1 合适人群 1.数据库事务特征我只是背过,并没有很深刻的理解. 2.数据库事务的隔离级别只是了解,并没有深刻理解,也没有在实际工作中体验使用过. 3.经常面试被人问起数据库加锁情况,一 ...

  3. Java8 面试基础知识宝典【主要以问题的形式记录,SE,EE,锁机制,框架,数据库等】

    目录 JavaSE 8 基础语法 9 Q1:简单说说Java有哪些数据类型 Q2:float number=3.4;有没有问题?为什么?默认类型[int.double] Q3:字符串拼接的方式以及效率 ...

  4. 数据库锁的概念与介绍

    数据库锁 锁的分类(使用方式划分) 悲观锁与乐观锁 悲观锁(Pessimistic Lock) 具有强烈的独占和排他特性.它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修 ...

  5. mysql隔离级别加锁情况_MySQL数据库事务各隔离级别加锁情况--read committed amp;amp; MVCC...

    上节回顾 上篇记录了我对MySQL 事务 隔离级别read uncommitted的理解. 这篇记录我对 MySQL 事务隔离级别 read committed & MVCC 的理解. 前言 ...

  6. linux mysql 释放x锁_MySQL 加锁处理分析-转载

    背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备 ...

  7. mysql limit锁_我所理解的MySQL五:锁及加锁规则

    mysql教程栏目介绍MySQL的第五篇文章,关于锁及加锁规则. MySQL 系列的第五篇,主要内容是锁(Lock),包括锁的粒度分类.行锁.间隙锁以及加锁规则等. MySQL 引入锁的目的是为了解决 ...

  8. 分布式锁(Distributed Lock)理论介绍

    在多线程环境中,线程之间通常使用互斥锁实现共享资源的独占访问.在多进程环境,特别是分布式环境,常使用分布式锁来实现共享资源的独占访问.简单来说,分布式锁就是指在分布式环境下,通过加解锁实现多节点对共享 ...

  9. 数据库事务特征、数据库隔离级别,各级别数据库加锁情况(含实操)--read committed MVCC...

    上节回顾 上篇记录了我对MySQL 事务 隔离级别** read uncommitted **的理解. 这篇记录我对 MySQL 事务隔离级别 read committed & MVCC 的理 ...

最新文章

  1. 神秘又强大的@SpringBootApplication注解
  2. bootloader烧写
  3. 用CSS写出一个下拉菜单小箭头
  4. Sublime Text 3 python和Package Control配置方法
  5. ITK:在一张图像中设置像素值
  6. Java并发编程的艺术,解读并发编程的优缺点
  7. *【CodeForces - 122D】Lucky Transformation(字符串问题,思维剪枝,优化,有坑,需注意的问题if的层次总结)
  8. 微内核和宏内核的区别(短小、精悍)
  9. strictmath_Java StrictMath rint()方法与示例
  10. mysql面试关联查询语句_sql语句多表联查语句的练习(面试题)
  11. HDU - 2102 A计划(双层BFS)
  12. 一次sendmsg的改造过程
  13. 模板题——快速幂,高斯消元
  14. 2020谷歌服务助手_华为mate30没法用谷歌?新加坡网友实测如何越过官方限制!...
  15. ectouch后台添加菜单
  16. 使用PR剪辑视频,mkv格式怎么无损转mp4
  17. Video标签的常用属性操作
  18. 重置计算机网络设置路由器,重新设置路由器的步骤
  19. HDP 之 Timeline Service 2.0
  20. 计算机建模和仿真实训报告,cad与cam实训报告范文3篇

热门文章

  1. Eclips 反编译
  2. 深度分解服务业细分领域O2O
  3. 小米路由器3G(R3G)刷潘多拉
  4. ❤️❤️❤️Unity废柴看过来,手把手教你做植物大战僵尸(十二)—— 向日葵生产太阳
  5. 如何用GameMakerStudio开发基于物理引擎的平台游戏 | Lynda教程 中文字幕
  6. 最近 火火火火 的 GitHub 项目!
  7. CES 2019上芯片巨头们的争夺焦点:光线追踪、“永远”在线PC、汽车...
  8. 俄罗斯方块练习中对 swift 语言的体会
  9. (Node+Vue+微信公众号开发)企业级产品全栈开发速成周末班
  10. Python之数据爬取数据可视化