MySql锁机制(全网最全、最详细、最清晰)

2023-11-04

1、MySql锁机制

锁机制的作用:

解决因为资源共享,而造成的并发问题。

没有锁机制时:

例如一号用户和二号用户都要去买同一件商品(假如这件商品是一件衣服),一号用户手速稍微快了一些,于是就先买到了这件衣服,但是因为没有“锁机制”,于是就造成了二号用户不知道这件衣服已经被人买了,所以就造成了“并发问题”。

有锁机制时:

但是有了“锁机制”,一号用户在买了衣服之后就会“对衣服进行加锁”,二号用户看到“衣服被加锁了”,于是就去“等待着衣服被解锁”。

在“衣服未被解锁”的过程中,衣服则会被一号用户进行“试穿”、“下单”、“付款”、“打包”、或者“不满意,取消订单”一系列的操作,这一系列操作之后“衣服会被解锁”。

如果一号用户这边觉得衣服还行打算买下来,在买完之后“衣服就会被解锁”,二号用户这边看到“衣服被解锁了”就会去查看衣服是否还存在,很明显已经不存在了,因为一号用户已经把衣服买了,如果一号用户“不满意,取消订单”,那么二号用户这边就可以购买这件衣服。

因此通过锁机制就很好的解决了买衣服造成的并发问题。

2、MySql锁的分类

按照“操作类型”分:

1、读锁(也叫“共享锁”):

对同一个数据(衣服),多个读操作可以同时进行,互不干扰。

2、写锁(也叫“互斥锁”)

如果当前写操作没有完毕(买衣服的一系列操作),则无法进行其他的读操作、写操作。

按照“操作范围”分:

1、表锁 :

一次性对一张表整体加锁。如MyISAM存储引擎使用表锁,开销小、加锁快;无死锁;但锁的范围大,容易发生锁冲突、并发度低。

2、行锁(与表锁的特性完全相反):

一次性对一条数据加锁。如InnoDB存储引擎使用行锁,开销大,加锁慢;容易出现死锁;锁的范围较小,不易发生锁冲突,并发度高(很小概率发生高并发问题:脏读、幻读、不可重复度、丢失更新等问题)。

3、页锁(几乎遇不见)

页锁的开销介于表锁和行锁之间,会出现死锁。锁定粒度介于表锁和行锁之间,并发度一般。

3、MySql表锁示例

准备工作:

1、创建两张表,表table和表lock

create table tab(
id int primary key auto_increment , 
name varchar(20)
)engine myisam;
insert into tab(name) values('tab1');
insert into tab(name) values('tab2');
insert into tab(name) values('tab3');
insert into tab(name) values('tab4');
insert into tab(name) values('tab5');
create table locktab(
id int primary key auto_increment , 
name varchar(20)
)engine myisam;
insert into locktab(name) values('locktab1');
insert into locktab(name) values('locktab2');
insert into locktab(name) values('locktab3');
insert into locktab(name) values('locktab4');
insert into locktab(name) values('locktab5');

2、再新建两个会话

加锁相关命令:

1、增加锁:

lock table 表1 read/write,表2 read/write,...;

2、释放锁:

unlock tables;

3、查看加锁的表:

show open tables;

加读锁(也叫“共享锁”):

会话192.168.11.101(1):

给表locktab加读锁:

lock table locktab read;
select * from locktab; --执行读操作(查),可以

delete from locktab where id =1; --执行写操作(增删改),不可以

操作没有加锁的表tab:

select * from tab; --读操作,不可以
delete from tab where id = 1; --写操作,不可以

结论:

1、如果某一个会话对A表加了read锁,则该会话可以对A表进行读操作、不能进行写操作;且该会话不能对其他表进行读、写操作。

2、即如果给A表加了读锁,则当前会话只能对A表进行读操作。

会话192.168.11.101(2),也就是其它会话:

操作加锁了的表locktab:

select * from locktab; --读操作(查),可以

delete from locktab where id =1; --写操作,会“等待”会话192.168.11.101(1)将锁释放

操作没有加锁的表tab:

select * from tab;  --读操作(查),可以
delete from tab where id = 1; --写操作(增删改),可以

再来在“会话192.168.11.101(1)”中把锁释放了,看看“delete from locktab where id =1;”是否会释放阻塞:

总结:

“会话192.168.11.101(1)”给表locktab加了锁,其他会话的操作:

1、可以对其他表(表locktab以外的表)进行读、写操作。

2、对表locktab:读操作可以,写操作需要等待释放锁。

加写锁(也叫“互斥锁”):

会话192.168.11.101(1):

给表locktab加读锁:

lock table locktab write;
select * from locktab; --读操作,可以
delete from locktab where id = 5; --写操作,可以

操作没有加锁的表tab:

select * from tab; --读操作,不可以
delete from tab where id = 3; --写操作,不可以

总结:

当前会话(会话192.168.11.101(1))可以对加了写锁的表进行任何操作(增删改查),但是不能操作(增删改查)其他表。

会话192.168.11.101(2):

操作加锁了的表locktab:

select * from locktab; --写操作,会阻塞

delete from locktab where id = 2; --写操作,也会阻塞

对“会话192.168.11.101(2)”中加写锁的表可以进行增删改查的前提是:等待“会话192.168.11.101(1)”释放写锁。

操作没加锁的表tab:

select * from tab; --读操作,可以
delete from tab where id = 2; --写操作,可以

MySQL表级锁的锁模式:

MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(DML)前,会自动给涉及的表加写锁。

所以对MyISAM表进行操作,会有以下情况:

1、对MyISAM表的读操作(加读锁),不会阻塞其他进程(会话)对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。

2、对MyISAM表的写操作(加写锁),会阻塞其他进程(会话)对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。

分析表锁定:

查看哪些表加了锁:

show open tables

1代表被加了锁

分析表锁定的严重程度:

show status like 'table%';

Table_locks_immediate:即可能获取到的锁数。

Table_locks_waited:需要等待的表锁数(如果该值越大,说明存在越大的锁竞争)。

一般建议:

Table_locks_immediate/Table_locks_waited > 5000, 建议采用InnoDB引擎,否则MyISAM引擎。

4、MySql行锁示例

准备工作:

unlock tables; --需要先释放之前加的表锁
create table linelock(
id int(5) primary key auto_increment,
name varchar(20)
)engine=innodb ;
insert into linelock(name) values('1');
insert into linelock(name) values('2');
insert into linelock(name) values('3');
insert into linelock(name) values('4');
insert into linelock(name) values('5');

为了研究行锁,暂时将自动commit关闭,“set autocommit = 0;”,以后需要通过“commit”关键字提交写操作:

set autocommit = 0;

mysql默认自动commit,oracle默认不会自动commit。

行锁,操作同一条数据:

会话192.168.11.101(1):写操作

insert into linelock values(6,'a6');

会话192.168.11.101(2):写操作,同样的数据

update linelock set name='ax' where id = 6;

总结:

1、如果会话x对某条数据a进行DML操作(研究时:关闭了自动commit的情况下),则其他会话必须等待会话x结束事务(commit/rollback)后,才能对数据a进行操作。

2、表锁是通过unlock tables,也可以通过事务解锁;行锁是通过事务解锁。

行锁,操作不同数据:

会话192.168.11.101(1): 写操作

insert into linelock values(8,'a8');

会话192.168.11.101(2): 写操作,不同的数据

update linelock set name='ax' where id = 5;

总结:

行锁,一次锁一行数据;因此如果操作的是不同数据,则不干扰。

行锁的注意事项:

1、如果没有索引,则行锁会转为表锁

先给字段“name”加个索引:

show index from linelock;

可以看到有一条索引,这是主键索引,建表创建主键的时候自动加的。

这是mysql的基础,无论是创建主键还是外键都会自动创建主键索引或外键索引。

给name加个索引:

alter table linelock add index idx_linelock_name(name);

会话192.168.11.101(1): 写操作

update linelock set name = 'ai' where name = '3';

会话192.168.11.101(2): 写操作,不同的数据

update linelock set name = 'aiX' where name = '4';

可以看到在索引没有失效的情况下所有会话都可以对数据进行写操作。

会话192.168.11.101(1): 写操作

update linelock set name = 'ai' where name = 3;

会话192.168.11.101(2): 写操作,不同的数据

update linelock set name = 'aiX' where name = 4;

可以发现,数据被阻塞了(加锁)。

原因:如果索引列发生了类型转换,则索引失效。 因此此次操作,会从行锁转为表锁。

2、行锁的一种特殊情况:间隙锁:值在范围内,但却不存在。

此时linelock表中 没有id=7的数据:

“update linelock set name ='x' where id >1 and id<9;”即在此where范围中,没有id=7的数据,则id=7的数据成为间隙。

间隙:Mysql会自动给间隙加锁(间隙锁)。即会自动给id=7的数据加间隙锁(行锁)。

行锁:如果有where,则实际加锁的范围就是where后面的范围(不是实际的值)。

如果仅仅是查询数据,能否加锁? 可以使用for update:

select * from linelock where id =2 for update;

通过for update对query语句进行加锁。

mysql中,以下三种方式都可以将自动提交关闭:

set autocommit =0;
start transaction;
begin;

行锁:

InnoDB默认采用行锁。

缺点:

比表锁性能损耗大。

优点:

并发能力强,效率高。

因此建议,高并发用InnoDB,否则用MyISAM。

行锁分析:

show status like '%innodb_row_lock%';

Innodb_row_lock_current_waits:当前正在等待锁的数量。

Innodb_row_lock_time:等待总时长。从系统启动到现在一共等待的时间。

Innodb_row_lock_time_avg:平均等待时长。从系统启动到现在平均等待的时间。

Innodb_row_lock_time_max:最大等待时长。从系统启动到现在最大一次等待的时间。

Innodb_row_lock_waits:等待次数。从系统启动到现在一共等待的次数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySql锁机制(全网最全、最详细、最清晰) 的相关文章

随机推荐

  • 从零开始搭建基于vue的electron项目

    从零开始搭建基于vue的electron项目 1 需求背景 最近正在为基于electron的新项目做准备 本文章将为大家演示从零开始搭建基于vue的electron项目步骤 2 解决方案 1 将Vue引入Electron项目常用的两种方案分
  • 03云计算与大数据学习之云存储

    文章目录 1 应知应会 2 认识云存储 云存储 云存储技术的两种架构 云存储的种类 云存储的应用领域 3 参考文献 1 应知应会 云存储是一个以数据存储和管理为核心的云计算系统 云存储由存储节点和控制节点两个部分组成 云存储系统的结构模型由
  • notepad++快捷键

    notepad 快捷键 https wenku baidu com view 9dec474e021ca300a6c30c22590102020640f254 html wkts 1676528962334 bdQuery notepad
  • QT QTextEdit QTextBrowser追加文本不换行

    QTextEdit QTextBrowser两个控件追加文本的接口使用方法都是一样的 以QTextBrowser为例 1 追加文本自动换行 textBrowser gt append hello textBrowser gt append
  • openssl engine 实现SM4 引擎

    openssl engine 实现SM4 引擎 一 openssl engine基本介绍 二 SM4引擎实现 1 Openssl定义好的主接口 2 定义bind函数 3 实现ciphers函数 4 定义算法结构evp cipher st 5
  • 动态规划 - 钢条切割问题

    已知钢条切割的不同长度对应的不同价格如下所示 长度i 1 2 3 4 5 6 7 8 9 10 价格pi 1 5 8 9 10 17 17 20 24 30 求输入长度 输出最佳的收益 详细理论知识见 算法导论第十五章 P359 书中给出三
  • maven 通过profiles管理不同环境的依赖和插件

    Profile能让你为一个特殊的环境自定义一个特殊的构建 profile使得不同环境间构建的可移植性成为可能 Maven中的profile是一组可选的配置 可以用来设置或者覆盖配置默认值 有了profile 你就可以为不同的环境定制构建 p
  • 基于SSM的客户管理系统的设计与实现

    项目描述 该项目采用了SSM作为后端开发框架 系统中分为管理员 客户经理 销售主管 和高管四种用户角色 在项目中实现了营销管理 服务管理 统计报表 基础数据管理以及 系统管理等功能模块 下载地址 http www hrxxkj com we
  • 【C语言】辗转相除法+更相减损术+秦九韶算法

    一 辗转相除法 1 简介 辗转相除法又叫欧几里得算法 假如需要求 1997 和 615 两个正整数的最大公约数 用欧几里得算法 是这样进行的 1997 615 3 余 152 615 152 4 余7 152 7 21 余5 7 5 1 余
  • JackSon的用法详解

    JackSon的用法详解 JackSon的用法详解
  • chisel测试指令

    第一步 chisel 转换成firrtl类型 sbt test only 包名 测试类名 第二步 firrtl转换成verilog 指向verilator TESTER BACKENDS verilator sbt test only 包名
  • VMware vSphere基础命令大全

    VMware vSphere是VMware公司的虚拟化平台 包括ESXi hypervisor和vCenter Server两大组件 作为vSphere平台的管理员 掌握常用的vSphere管理命令是必要的 这些命令主要在vSphere C
  • proto文件支持继承吗_关于ES6中继承的问题 B继承A B.__proto__ = A?

    B proto proto 确实是 Function prototype 但首先它的原型是 A 其原型的原型才是函数原型 因为定义在 A 上的静态方法 B 也要继承 更新 每一个对象都有原型 但是对象的原型并不一定是对象的构造函数的 pro
  • runoob.com菜鸟教程-redis命令查询

    http www runoob com redis redis transactions html
  • asn1c编解码时 Assertion ‘lb <= ub‘ failed问题

    近期在使用asn编解码时提示 per support c 238 per long range rebase Assertion lb lt ub failed 经过查找资料和分析 找到解决办法 如下 修改INTEGER c 文件
  • 瑞芯微Rockchips RK3368对比晶晨Amlogic S905

    回首过去的2015上半年 国内网络机顶盒64位处理器一直被瑞芯微RK3368垄断着 到了2015年下半年 随着天猫魔盒M13和小米盒子3等电视盒子的曝光 预售与上市 瑞芯微RK3368的在电视盒子中64位处理器的垄断地位也被打破 因为天猫魔
  • 如何在vue项目中引入字体图标

    第一步 进入阿里图标库 选择自己需要的图标 第二步 选择之后不要点击下载 点击加入购物车 第三步 点击右上角的购物车 然后点击添加至项目可以新建项目名称 第四步 然后点击红字复制代码 注 画红框的是引用字体图标时的名字 点击画框的地方 在新
  • Qt设计师的简单使用(ui设计界面的简单使用)

    文章目录 一 界面的基本介绍 二 添加控件 2 1 添加控件 2 2 设置控件属性 三 布局器的使用 3 1 布局器介绍 3 2 简单布局 3 3 复杂布局 3 4 带分裂器的布局 四 拓展 4 1 添加模块窗口 4 2 转到槽的使用 4
  • M3U8视频AES解密播放

    在网站上看到一些有意思的视频想要下载下来的时候 发现没有找不到mp4格式的地址 因为该网站视频播放是HLS HTTP Live Streaming 技术 HLS是Apple公司研发的流媒体传输技术 包括一个m3u8的索引文件 多个ts分片文
  • MySql锁机制(全网最全、最详细、最清晰)

    1 MySql锁机制 锁机制的作用 解决因为资源共享 而造成的并发问题 没有锁机制时 例如一号用户和二号用户都要去买同一件商品 假如这件商品是一件衣服 一号用户手速稍微快了一些 于是就先买到了这件衣服 但是因为没有 锁机制 于是就造成了二号