02_共享锁和排他锁

共享锁和排他锁

文章目录

简介

MySQL 中的共享锁和排他锁是两种最基本的锁类型,它们用于控制并发事务对数据库资源的访问(事务隔离),以保证数据一致性和完整性。


共享锁(Shared Lock, S Lock)

简介

共享锁,也被称为读锁。共享锁允许多个事务同时读取某一资源(如一行或一张表)的锁,但不允许任何事务修改该资源。

原理

当一个事务对某资源加共享锁后,其他事务可以继续对该资源加共享锁进行读取操作,但不能加排他锁进行写入操作,直到已释放所有共享锁。

使用方式
sql 复制代码
SELECT * FROM table_name WHERE condition LOCK IN SHARE MODE;

在查询语句后面增加LOCK IN SHARE MODE,MySQL会对查询结果中的每行都加共享锁。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。

加锁流程
  1. 事务请求共享锁:事务发出加共享锁的请求。
  2. 加锁操作:MySQL 检查是否有其他事务持有该资源的排他锁。如果没有,则加共享锁成功。(如果此时该资源被其他事务添加了共享锁,当前事务会直接再次添加共享锁)
  3. 执行操作:持有共享锁的事务可以读取该资源。
  4. 释放锁:事务提交或回滚后,释放共享锁。
使用场景
  • 需要多个事务同时读取同一资源而不希望被修改时,例如并发查询操作。

排他锁(Exclusive Lock, X Lock)

简介

排他锁又称写锁,是一种只允许一个事务独占访问某一资源的锁,其他事务不能对该资源加任何类型的锁。

原理

当一个事务T对某资源添加了排他锁之后,该事务T可以自由地读取和修改该资源。此时,其他事务不能对该资源添加任何共享锁或者排他锁,即无法对该资源进行读取和修改,直到事务 T 的排他锁被释放。这样保证了写操作的完整性和独立性。

使用方式
sql 复制代码
SELECT * FROM table_name WHERE condition FOR UPDATE;

在查询语句后面增加FOR UPDATE,MySQL会对查询命中的每条记录都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阳塞。

加锁流程
  1. 事务请求排他锁:事务发出加排他锁的请求。
  2. 加锁操作:MySQL 检查是否有其他事务持有该资源的共享锁或排他锁。如果没有,则加排他锁成功。
  3. 执行操作:持有排他锁的事务可以读取和修改该资源。
  4. 释放锁:事务提交或回滚后,释放排他锁。
使用场景
  • 需要独占访问和修改某一资源时,例如更新操作、删除操作。

对比

特性 共享锁 (S Lock) 排他锁 (X Lock)
锁定粒度 行级、表级 行级、表级
并发性 高(允许多个事务同时读取) 低(独占访问,其他事务无法读取或修改)
使用场景 并发读操作 独占写操作
锁兼容性 与其他共享锁兼容,不与排他锁兼容 与任何其他锁都不兼容

注意事项

  • 使用锁时需要注意死锁的可能性。死锁是指两个或多个事务在等待对方释放锁,导致所有事务都无法继续执行的情况。InnoDB存储引擎有自动死锁检测和解决机制,但设计数据库操作时仍需谨慎。
  • 锁的使用需要平衡并发性和数据一致性的需求。过度使用锁可能会降低数据库的并发性能,不当的锁使用可能会导致数据不一致。

结论

共享锁和排他锁是 MySQL 中实现并发控制的基本机制。共享锁允许多个事务并发读取资源,而排他锁确保单个事务独占访问和修改资源。根据具体需求选择合适的锁类型,可以有效地提高数据库的并发性能和数据一致性。

相关推荐
Fleshy数模5 小时前
CentOS7 安装配置 MySQL5.7 完整教程(本地虚拟机学习版)
linux·mysql·centos
az44yao6 小时前
mysql 创建事件 每天17点执行一个存储过程
mysql
秦老师Q7 小时前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
橘子138 小时前
MySQL用户管理(十三)
数据库·mysql
Dxy12393102168 小时前
MySQL如何加唯一索引
android·数据库·mysql
我真的是大笨蛋8 小时前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化
怣508 小时前
MySQL数据检索入门:从零开始学SELECT查询
数据库·mysql
人道领域8 小时前
javaWeb从入门到进阶(SpringBoot事务管理及AOP)
java·数据库·mysql
千寻技术帮9 小时前
10404_基于Web的校园网络安全防御系统
网络·mysql·安全·web安全·springboot
spencer_tseng10 小时前
MySQL table backup
mysql