当前位置: 首页 > news >正文

MySQL:行级锁

MySQL中的行级锁是数据库锁机制中粒度最细的一种,它只锁定事务需要修改的数据行,而不是整个表或数据库。行级锁能够显著提高数据库的并发性能,减少锁冲突。

行级锁的类型

MySQL中的行级锁主要有以下几种类型:

  1. 记录锁(Record Lock)

    • 直接锁定被操作的数据行。
    • 分为共享锁S锁)和排他锁X锁)。S锁允许其他事务读取被锁定的数据行,但不允许修改;X锁则不允许其他事务读取或修改被锁定的数据行。
    • 示例:SELECT * FROM your_table WHERE id=1 FOR UPDATE; 会对id为1的数据行加X锁。
  2. 间隙锁(Gap Lock)

    • 锁定一个范围,但不包括该范围内的任何实际数据记录。
    • 主要用于阻止其他事务在锁定数据范围内插入新数据,防止幻读现象的发生。
    • 只存在于可重复读(Repeatable Read)隔离级别。
    • 示例:在id为(3,5)的范围内加间隙锁,会阻止其他事务插入id为4的记录。
  3. 临键锁(Next-Key Lock)

    • 记录锁和间隙锁的组合,锁定一个范围并包括边界上的记录。
    • 防止其他事务在范围内插入新记录或修改被锁定的记录。
    • 只在可重复读或更高隔离级别下生效。
    • 示例:在id为(3,5]的范围内加临键锁,会阻止其他事务插入id为4的记录或修改id为5的记录。

行级锁的实现原理

MySQL中的InnoDB存储引擎支持行级锁,它是通过给索引项加锁来实现的。这意味着,只有通过索引条件来检索数据,才能使用行级锁;否则,将使用表级锁。行级锁的开销相对较大,但锁定粒度最小,能够显著提高数据库的并发性能。

行级锁的使用方式

显式获取行级锁

在 MySQL 中,使用 SELECT 语句时,通过使用 LOCK IN SHARE MODEFOR UPDATE 子句,可以在读取数据时实现共享锁和排他锁的锁定,以控制并发事务之间对数据的访问和更新,从而控制并发事务对数据的访问和更新。

显式锁定需要开发人员负责管理和释放锁定,避免出现死锁和性能问题。

共享锁

SELECT … LOCK IN SHARE MODE

当使用 SELECT 语句查询数据时,可以添加 LOCK IN SHARE MODE 子句来对查询结果集中的数据行进行共享锁(Shared Lock)的锁定。

共享锁允许其他事务并发地读取相同的数据,但阻止其他事务对数据行进行写操作,保证了读取的数据不会被修改。其他事务可以获取共享锁以读取数据,但等待写锁(Exclusive Lock)的事务无法进行写操作。

例如:

SELECT * FROM table_name LOCK IN SHARE MODE;
排他锁

SELECT … FOR UPDATE:

当使用 SELECT 语句查询数据时,可以添加 FOR UPDATE 子句来对查询结果集中的数据行进行排他锁(Exclusive Lock)的锁定。

排他锁会阻止其他事务对数据行进行读取或写入操作,只有持有排他锁的事务可以进行数据的更新。其他事务在遇到已被锁定的数据行时,会进入等待状态,直到排他锁被释放。

例如:

SELECT * FROM table_name FOR UPDATE;
隐式获取行级锁
  • 在执行 UPDATEDELETE 等修改数据的操作时,MySQL会自动为涉及的数据行加X锁(排他锁)。
  • 无需显式地使用锁语句,但需要注意事务的开启和提交。

注意事项

  1. 锁的粒度与并发性能:行级锁的粒度最小,但开销也最大。在设计数据库和查询时,应权衡锁的粒度与并发性能之间的关系。

  2. 死锁:当两个或多个事务相互等待对方释放锁时,会发生死锁。MySQL会自动检测并处理死锁,但过多的死锁会影响数据库的性能。

  3. 索引优化:合理使用索引可以提高行级锁的效率,减少锁的竞争。在设计数据库时,应优先考虑为经常查询的列添加索引。

  4. 事务隔离级别:不同的隔离级别会影响行级锁的行为。例如,在可重复读隔离级别下,InnoDB会使用临键锁来防止幻读现象的发生。

通过了解MySQL行级锁的类型、实现原理、使用方式以及注意事项,我们可以更好地利用行级锁来提高数据库的并发性能和数据一致性。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 车载音频开发(一):从看懂wav开始
  • DUILib 创建自定义文本编辑控件
  • 【Python】模块
  • 《Windows API每日一练》24.1 WinSock简介
  • Java中的notify()与notifyAll()区别
  • 探展2024世界人工智能大会之合合信息扫描黑科技~
  • Harmony学习(四)(应用程序框架基础)
  • 电影票房数据的获取,可以控制数量,并导出表格或csv
  • filebeat + logstash使用笔记
  • 优化PyCharm:让IDE响应速度飞起来
  • 一键生成视频并批量上传视频抖音、bilibili、腾讯(已打包)
  • 【vulnhub】The Ether: Evil Science靶机
  • 浦语提示词工程实践
  • 从文本到图像:深度解析向量嵌入在机器学习中的应用
  • 面试经验|问题
  • Bootstrap JS插件Alert源码分析
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • ES6 学习笔记(一)let,const和解构赋值
  • Git 使用集
  • JavaScript 一些 DOM 的知识点
  • k个最大的数及变种小结
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • python docx文档转html页面
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • React的组件模式
  • Vue2.x学习三:事件处理生命周期钩子
  • webpack入门学习手记(二)
  • 百度小程序遇到的问题
  • 使用agvtool更改app version/build
  • 想写好前端,先练好内功
  • 智能合约Solidity教程-事件和日志(一)
  • No resource identifier found for attribute,RxJava之zip操作符
  • 积累各种好的链接
  • ​批处理文件中的errorlevel用法
  • #HarmonyOS:Web组件的使用
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (SpringBoot)第二章:Spring创建和使用
  • (web自动化测试+python)1
  • (剑指Offer)面试题34:丑数
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (一)Thymeleaf用法——Thymeleaf简介
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转)linux下的时间函数使用
  • (转)Oracle存储过程编写经验和优化措施
  • (转)平衡树
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .net wcf memory gates checking failed
  • .Net 路由处理厉害了
  • .Net7 环境安装配置
  • .NET未来路在何方?
  • .Net中wcf服务生成及调用
  • @DataRedisTest测试redis从未如此丝滑