MySQL中的表锁,行锁,排它锁,共享锁

行锁与表锁详解:原理、区别与面试要点 本文深入解析了数据库中的行锁与表锁机制。行锁锁定单行记录,具有高并发特性,适用于OLTP系统;表锁锁定整表,适合批量操作。文章对比了两者的核心区别,包括锁定粒度、并发性能和适用场景等,并介绍了高级面试要点如锁升级、意向锁机制和死锁处理。同时提供实战建议,如索引设计、SQL优化和锁监控技巧,最后列举常见面试问题及解答。掌握这些知识对数据库性能优化和高并发系统设计至关重要。 阅读详情

表锁与行锁


1 ) 概念

  • 在使用mysql的时候,如果同时向 mysql 里边批量进行更新, 插入或删除动作
  • 数据库里的数据不会出问题, 在 mysql内部,它其实自带了一个锁的功能
  • 而它内部有的是用了锁,有的没有用锁,没用锁的需要咱们利用锁来自行处理
  • mysql 从范围的角度来讲,支持表锁和行锁
    • 表锁: 把整个表锁住
      • 你对这张表的任意行在做操作,你都得阻塞住
      • 还有就是, 占用这把锁的那个人处理完了下一个才能进来
    • 行锁: 它只锁了某一行
      • 表里的某一行, 比如你操作申请到锁了,下一个人来处理这一行, 它就会阻塞住
      • 如果下个人处理的是别的行,是允许的
    • 一般而言,行级锁是更好一些的锁
      • 因为我用哪个数据,我就锁住哪些数据即可
      • 当然也会有一些特殊的情况需要表级锁
  • 创建mysql的表的时候,是可以指定引擎的
    • Myisam 引擎: 只支持表锁,不支持行锁
      • 无论怎么加锁都是行锁
    • InnoDB 引擎: 支持行锁和表锁
      • 如果进行搜索时,利用索引的形式去搜,也就是命中索引
      • 搜到的某一行数据或某些个数据,它就可以利用行锁
      • 如果搜索的时候没有用到索引,比如说全表扫描
      • 那它会对整个表都锁住,就应用表锁了
  • 为了能够去用锁的时候,力度更细,InnoDB 是一个很好的选择
  • 所以,项目开发中,我们都选择去使用 InnoDB 引擎
  • 对 InnoDB 引擎创建的表,如果对这张表进行 update、insert、delete 做行为内部
  • 实际上它会先申请锁,然后再去执行,执行完,再释放锁
  • 如果很多人都在执行update操作,内部会把锁加上,不会造成数据混乱的问题
  • 它内部一定会排着队,逐个执行的
  • 但要执行 select,默认情况下,不会加锁,因为查询,拿过来加锁,没什么用
  • 如果以后在特定的条件,就需要查询的时候人为申请一把锁也是可以的
  • 它的使用规范是: 基于事务 + 特殊语法来实现

排它锁和共享锁

  • mysql 按照类型分,可分为 排它锁 和 共享锁

  • 先创建一张表

    create table `L1`(
      `id` int(11) not null auto_increment,
      `name` varchar(255) default null,
      `count` int(11) default null,
      primary key (`id`)
    ) engine=innodb default charset=utf8;
    
  • 在这张表中操作 insert 很多数据,这里就不做操作了

1 ) 排它锁

  • 主要语法 for update, 示例

    begin; -- 或 start transaction;
      select * from L1 where name='wang' for update; -- 注意,这里name不是索引,使用表锁
    commit; -- 事务结束,锁释放
    
    begin;
      select * from L1 where id=1 for update; -- 注意,这里id是索引,使用行锁
    commit;
    
  • 如果事务不结束,其他人操作,都会受到阻塞,进行不下去

  • 需要等到本人commit之后,才能结束锁,其他人才能继续

应用场景

  • 抢购与库存减量
  • update 操作默认加锁,如果当还剩最后一件,再执行就会出问题,会出现 -1 的问题
  • 这样是不合适的
    update goods set count=count-1 where id=3
    
  • 解决方案是使用排它锁,如下

sql操作示例

begin;
select count from goods where id=3 for update;
-- 获取个数进行判断
if 个数 > 0:
  update goods set count=count-1 where id=3;
else:
  -- 抢光了的处理
commit;

py操作

import pymysql
import threading

def task():
  # 建立连接
  conn = pymysql.connect(host='xxx.xxx.xxx.xxx', port=3306, user='root', password='xxxx', charset='utf8', db='userdb');
  # 限定结果格式,如下面的 fetchone 后,是这样的格式: { id: 1, age: 10 }
  # 如果是 fetchall, 则是这样的格式 ({ id: 1, age: 10 }, { id: 2, age: 11 })
  cursor = conn.cursor(pymysql.cursors.DictCursor)
  conn.begin() # 开启事务
  cursor.execute('select id, age from tran where id=2 for update') # 排它锁
  result = cursor.fetchone()
  current_age = result['age']
  if current_age > 0:
      cursor.execute('update tran set age==age-1 where id=2')
  else:
      print('已售完')
  conn.commit()
  cursor.close()
  conn.close()

def run():
  # 创建5个线程, 都去执行 task
  for i in range(5):
    t = threading.Thread(target=task)
    t.start()

if __name__ == '__main__':
  run()

2 ) 共享锁

主要语法是: lock in share mode

sql 用法示例

begin;
  select * from L1 where name='xxx' lock in share mode; -- name列不是索引,使用表锁
commit;

begin;
  select * from L1 where id=1 lock in share mode;    -- id列是索引 (行锁)
commit;

和排它锁的区别是: 加锁之后,其他可读,不可写

场景举例

  • 目前有 A 和 B 两张锁
  • 需要在 A 表中插入一条数据,插入前需要确保 B 表中相关的一条数据存在
  • 但是,很可能在A插入的时候,B中的关键数据被删除
  • 这时候就可以用 共享锁 防止B中相关数据被删除

sql 实现

begin;
  select * from B where id=1 lock in share mode;    -- id列是索引 (行锁)
  insert into A(name) values('wang');
commit;
  • 一定要注意这一点:加锁之后,可以读,不可写(update, delete, insert)
  • 实际上应用场景不多
mysql锁表原因及解决方案 一、导致锁表的原因 1、锁表发生在insert update 、delete 中 2、锁表的原理是 数据库使用独占式封锁机制,当执行上面的语句时,对表进行锁住,直到发生commite 或者 回滚 或者退出数据库用户 3、锁表的原因 第一、 A程序执行了对 tableA 的 insert ,并还未 commite时,B程序也对tableA 进行insert 则此时会发生资源正忙的异... 阅读详情

相关推荐

别再死记硬背了!用‘瞬时极性法’5分钟搞定三极管反馈电路类型判断

本文介绍了使用‘瞬时极性法’快速判断三极管反馈电路类型的高效技巧。通过假设输入信号变化并追踪传递路径,该方法能准确区分正负反馈、电压电流反馈、串联并联反馈及交直流反馈,避免传统死记硬背的弊端,显著提升电路分析效率。

weixin_42524708的博客 185

MySQL锁机制详解-表锁与行锁

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算机资源,如CPU、RAM、I/O等的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题。此外,锁冲突也是影响数据库并发访问性能的一个重要因素。

huangjhai的博客 1万+

STM32H745xI双核芯片SMPS/LDO配置误区:从复位失败到精准排查的实战复盘

本文详细分析了STM32H745xI双核芯片在SMPS/LDO配置中的常见误区,特别是复位失败问题的排查过程。通过对比参考板与故障板的波形数据,揭示了电感选型不当导致的电源稳定性问题,并提供了硬件设计检查清单和调试技巧,帮助开发者避免类似陷阱。

weixin_42531588的博客 265

Mysql中各类锁的机制图文详细解析(全)

目录1. 定义1. 表锁(读写锁)2. 行锁3. 页级锁4. 间隙锁5. 总结6. 补充 1. 定义 锁是计算机协调多个进程或线程并发访问某一资源的机制。 在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。 锁的分类 从对数据操作的类型 读锁(共享锁):针对同一份数据,多个读操作可以

码农研究僧的博客 3033

米哈游 AI产品经理面试题精选:10道高频考题+答案解析(附PDF)

米哈游是全球知名游戏开发商,以《原神》《崩坏》系列著称,专注二次元文化与AI技术创新。本文整理了10道AI产品经理面试题,涵盖Transformer架构、智能NPC设计、机器学习应用、AIGC产品规划等核心领域。题目既考察技术理解(如RAG原理、多模态模型),又关注产品落地(游戏平衡性优化、伦理安全),同时强调跨团队协作能力。参考答案均结合米哈游业务场景,体现技术驱动与玩家体验并重的产品思维,展现AI在游戏行业的创新应用前景。

ZHHHHH15的博客 683

Linux ELF文件解析:从file到readelf的完整工具链指南

ELF(可执行与可链接格式)是Linux系统中二进制文件的标准格式,定义了程序加载、内存布局和元数据组织方式。其核心原理在于通过程序头表描述执行视图、节区头表描述链接视图,实现代码与数据的结构化存储。这一格式的技术价值在于为程序调试、安全审计和性能优化提供了底层支持,尤其在动态链接、符号解析和内存保护机制中发挥关键作用。在应用场景上,系统管理员依赖ELF分析工具解决库依赖问题,安全研究员通过检查安全属性评估漏洞风险,开发者则利用反汇编进行代码调试。本文聚焦于file、readelf、objdump等工具链的

weixin_42691065的博客 635

什么是行锁,什么是表锁?

在数据库中,行锁和表锁是用于控制并发访问的机制。

m0_57836225的博客 1668

生信人的一天~HIFI数据+HIC数据组装基因组

HIFI+HIC数据组装基因组!

qq_43337286的博客 9530

MySQL中的锁(表锁、行锁,共享锁,排它锁,间隙锁)

本文参考: http://mysqlpub.com/thread-5383-1-1.html http://blog.youkuaiyun.com/c466254931/article/details/53463596 有很多是转载合并过来。锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的 计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证

程序老兵的博客 4万+

解决Word中英文混排的5个常见排版问题(含单词换行、间距调整等)

本文详细解析Word中英文混排的5大常见排版问题,包括单词换行、间距调整、标点混用等,提供专业解决方案。通过设置段落格式、调整兼容性选项和使用字体组合等技巧,帮助用户轻松解决文档排版难题,提升专业性和阅读体验。

vim8coder的博客 1342

S7-200SMART 的运动控制(一)向导配置具体步骤(图文)

S7-200SMART 的运动控制(一)向导配置具体步骤(图文)

Robot_PLC_HMI_Automation 3851

MySQL中的乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念...

下文的所有介绍,都是基于InnoDB存储引擎,其他引擎的表现,会有较大的区别。   乐观锁 用数据版本(Version)记录机制实现,是乐观锁最常用的一种实现方式。什么是数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的“version”字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加1。当我们提交更新的时候,判断数据...

是金子总会花光的 373

Harmony:C# 动态代码补丁的5大秘密武器

Harmony 是一个开源库,它允许你在运行时修改托管代码(即使用 .NET 或 Mono 编译的语言编写的应用程序)。它通过利用 AOP(面向切面编程)的思想,可以在不重新编译代码的情况下添加、替换或修改方法的行为。这对于游戏模组(Modding)、插件开发以及调试工具非常有用。安装 Harmony要使用 Harmony,你需要首先安装它。Harmony 作为一个 NuGet 包,可以直接通过 Visual Studio 的 NuGet 包管理器进行安装。安装步骤打开 Visual Studio。

java专栏 1193

Mysql中的锁机制(表锁、行锁,共享锁,排它锁,间隙锁)

原文:http://blog.youkuaiyun.com/soonfly/article/details/70238902 **锁是计算机协调多个进程或线程并发访问某一资源的机制。**在数据库中,除传统的 计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一 个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从...

waS_TransvolnoS的博客 379

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

MySQL中的乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念

下文的所有介绍,都是基于InnoDB存储引擎,其他引擎的表现,会有较大的区别。   乐观锁 用数据版本(Version)记录机制实现,是乐观锁最常用的一种实现方式。什么是数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的“versio...

dreamli199的博客 260

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

MySQL中的锁(表锁、行锁,共享锁,排它锁,间隙锁)与避免死锁

目录 MySQL锁概述 MyISAM表锁 如何加表锁 查询表级锁争用情况 并发插入(Concurrent Inserts) MyISAM的锁调度 InnoDB锁 获取InonoD行锁争用情况 InnoDB的行锁模式及加锁方法 InnoDB行锁实现方式 间隙锁(Next-Key锁) 什么时候使用表锁 关于死锁 小结 锁是计算机协调多个进程或线程并发访问某一资源的机制。在...

weweeeeeeee的博客 535
上一篇: MySQL中的事务, 特性及应用
下一篇: MySQL中的连接池
Wang's Blog
博客等级 码龄12年 7433粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值