mysql 系列:锁和它的运用

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 数据库是一个允许多用户、多会话、多线程访问的系统。为了在并发访问中能保证数据的一致性和完整性,一般会使用事务来做控制,外加锁来作为辅助手段。所以今天整理了一下锁的相关知识,看看它在事务里是怎么配合使用的。

前言

数据库是一个允许多用户、多会话、多线程访问的系统。为了在并发访问中能保证数据的一致性和完整性,一般会使用事务来做控制,外加锁来作为辅助手段。所以今天整理了一下锁的相关知识,看看它在事务里是怎么配合使用的。

锁的分类

我们先来看下锁的分类及其作用有哪一些,以便能更好的分析运用场景。

乐观/悲观锁

乐观锁:在读取数据时会假设各个事务互不影响,它们会处理好属于自己的那部分数据。如果在更新数据时,发现有其他事务修改了属于自己的数据,则会回滚之前的一切操作。

悲观锁:采取了先获取锁再访问的保守策略,如果已经有其他事务获取了锁,则必须等待锁释放才能继续。

共享/排它锁

共享锁:又称读锁,当前事务在读取时,允许其他事务并发读取,但不允许其他事务上排它锁,必须等自己释放了才能继续。

排它锁:又称写锁,在写锁占有时,如果其他事务想上读写锁,则得排队等待。

表锁/行锁

表锁:在操作数据时,直接将整张表锁住,操作粒度很大,很容易让其他事务在等待,但不会产生死锁。

行锁:针对的是行记录的并发控制,锁粒度很细,能支持高并发,但是不排除会有死锁情况产生。在 mysql 里行锁依赖索引实现,如果没有索引存在,则会直接进行表锁

其中,行锁还细分出了下面几种锁:

记录锁:只锁住某一条记录。当对唯一索引(包括主键)进行精确查询时,会使用记录锁。

间隙锁:当使用范围查询时,会对符合条件的区间数据上锁。在涉及到普通索引(即不是唯一索引)的查询时,都会使用间隙锁。

Next-key 锁:临建锁,可以理解为 记录锁 + 间隙锁。当对唯一索引进行范围查找或对唯一索引进行查找但结果不存在时(可以理解为锁住不存在的记录),会使用临建锁。

上面的间隙锁、临建锁有效的防止了事务幻读情况产生,避免了在查找期间有数据新增或删除。

意向锁

意向锁是属于表锁的一种,它仅仅表示一种操作意向。当我们使用粒度比较小的行锁时,在检测是否有锁时,需要一行一行的检查,效率较低。

有了意向锁之后,则不需一行一行的排查,只需检测对应的意向锁即可。

意向锁有意向共享锁,以及意向排它锁。mysql 规定事务在上共享/排它锁时,必须能先获取到兼容的意向锁,否则必须等待锁的释放。

例如当前数据上已有意向共享锁,如果此时其他事务想上排它锁,则是不兼容的,必须等待释放。关于意向锁和共享/排它锁的兼容性表如下:

意向共享锁 意向排它锁
共享锁 兼容 互斥
排它锁 互斥 互斥

MVCC

MVCC 并不属于锁操作里的东西,但是它是事务隔离级别里会运用到的技术,并且由于它有类似快照数据的功能,所以使用 MVCC 时能很大程度的减少锁的使用,减少了并发冲突。具体可以看看这篇文章:MVCC

事务里锁的运用

在之前的文章事务解释里我们谈到了事务的隔离性,而事务的隔离性离不开锁的运用,所以现在就让我们来看看具体的使用吧。

可重复读

可重复读使用的是 MVCC 快照,所以在读取数据时大多数时候不需要使用锁。

但使用了 UPDATE, DELETE,或 SELECT with FOR UPDATE(排它锁) 或 FOR SHARE(共享锁),则会根据下面的情况来使用锁:

  • 在唯一索引上精确查找某条记录时,使用记录锁
  • 对于其他的搜索,InnoDB 将会锁定扫描到的索引范围,使用间隙锁或临建锁来防止幻读的产生

读提交

也是使用 MVCC 机制来读取数据,不过在使用 UPDATE, DELETE,或 SELECT with FOR UPDATE(排它锁) 或 FOR SHARE(共享锁)时和上面的机制不一样,当存储引擎将筛选到的记录交给 mysql server 层后,会对不相干的数据进行解锁,所以不会涉及间隙锁或临建锁。

它们只会在做外键约束检查和重复键检查时使用到。

由于间隙锁的禁用,可能会出现幻读现象。

未提交读

在 mysql 的 innodb 存储引擎里做 SELECT操作不会做任何锁动作,如果是 myisam 存储引擎,则会上共享锁。

如果使用UPDATE, DELETE,或 SELECT with FOR UPDATE(排它锁) 或 FOR SHARE(共享锁)则和读提交一样的原则。

可序列化读

可序列化读在使用 select 时,一般会自动的转化为 SELECT ...
FOR SHARE(共享锁) ,以保证读写序列化。

总结

本文介绍了锁的分类以及锁在事务里的使用,大多数时候 mysql 的事务都是会自动进行锁动作,并不需要我们干涉。

所以当我们在使用 SELECT with FOR UPDATE(排它锁) 或 FOR SHARE(共享锁)等显示上锁语句时要特别注意性能损耗,有可能产生间隙锁、临建锁导致不相干的记录也会被阻塞等待

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
MySQL数据库进阶第五篇(锁)
MySQL数据库进阶第五篇(锁)
|
3天前
|
关系型数据库 MySQL 数据库
Mysql的锁
本文介绍了MySQL中表级锁和行级锁的区别,其中MyISAM仅支持表级锁,而InnoDB支持表级锁和行级锁,默认为行级锁。表级锁锁定整个表,实现简单,资源消耗少,但并发度低;行级锁仅锁定相关记录,减少冲突,提高并发度,但加锁开销大。此外,还介绍了共享锁和排他锁的概念及意向锁的作用。
|
20天前
|
监控 关系型数据库 MySQL
在Linux中,mysql的innodb如何定位锁问题?
在Linux中,mysql的innodb如何定位锁问题?
|
26天前
|
存储 SQL 关系型数据库
深入MySQL锁机制:原理、死锁解决及Java防范技巧
深入MySQL锁机制:原理、死锁解决及Java防范技巧
|
26天前
|
存储 SQL 关系型数据库
深入解析MySQL事务机制和锁机制
深入解析MySQL事务机制和锁机制
|
1月前
|
SQL 存储 关系型数据库
"MySQL增列必锁表?揭秘InnoDB在线DDL,让你的数据库操作飞一般,性能无忧!"
【8月更文挑战第11天】在数据库领域,MySQL凭借其稳定高效的表现深受开发者喜爱。对于是否会在给数据表添加列时锁表的问题,MySQL的行为受版本、存储引擎等因素影响。从5.6版起,InnoDB支持在线DDL,可在改动表结构时保持表的可访问性,避免长时间锁表。而MyISAM等则需锁表完成操作。例如,在使用InnoDB的表上运行`ALTER TABLE users ADD COLUMN email VARCHAR(255);`时,通常不会完全锁表。虽然在线DDL提高了灵活性,但复杂操作或大表变更仍可能暂时影响性能。因此,进行结构变更前应评估其影响并择机执行。
45 6
|
1月前
|
存储 SQL 关系型数据库
MySQL中的update操作与锁机制
本文探讨MySQL中`UPDATE`操作的自动加锁机制及其对数据一致性的保障作用。尤其在InnoDB存储引擎下,系统会在涉及索引的更新操作中加行锁或间隙锁,防止多事务并发修改同一条记录。通过福利码兑换系统的实例展示,当线程A开启事务更新库存时,线程B试图更新相同记录会被阻塞,直至线程A提交。此外,文章还介绍了乐观锁及版本号控制等策略进一步提升并发性能的方法。作者:小明爱吃火锅,来源:稀土掘金。
|
3月前
|
存储 SQL 关系型数据库
【MySQL技术内幕】6.3-InnoDB中的锁
【MySQL技术内幕】6.3-InnoDB中的锁
177 57
|
18天前
|
关系型数据库 MySQL 数据库
MySQL MVCC和间隙锁有什么区别?
【8月更文挑战第24天】MySQL MVCC和间隙锁有什么区别?
31 0
|
2月前
|
SQL 关系型数据库 MySQL
(八)MySQL锁机制:高并发场景下该如何保证数据读写的安全性?
锁!这个词汇在编程中出现的次数尤为频繁,几乎主流的编程语言都会具备完善的锁机制,在数据库中也并不例外,为什么呢?这里牵扯到一个关键词:高并发,由于现在的计算机领域几乎都是多核机器,因此再编写单线程的应用自然无法将机器性能发挥到最大,想要让程序的并发性越高,多线程技术自然就呼之欲出,多线程技术一方面能充分压榨CPU资源,另一方面也能提升程序的并发支持性。
167 3

热门文章

最新文章