【mysql共享锁与排他锁】

news/2025/2/22 20:56:16

MySQL共享锁(Shared Lock)与排他锁(Exclusive Lock)总结

1. 基本概念
  • 共享锁(S锁)

    • 作用:用于读取操作(读锁)。
    • 特点:允许多个事务同时持有共享锁,但阻塞其他事务的排他锁
    • 语法:通过 SELECT ... LOCK IN SHARE MODE 显式加锁。
  • 排他锁(X锁)

    • 作用:用于写入操作(写锁)。
    • 特点:独占数据,阻塞其他事务的共享锁和排他锁
    • 语法:通过 SELECT ... FOR UPDATE 或写操作(如 UPDATEDELETE)隐式加锁。

2. 核心区别
特性共享锁(S锁)排他锁(X锁)
兼容性与其他共享锁兼容与其他所有锁不兼容
阻塞行为仅阻塞排他锁阻塞共享锁和排他锁
使用场景高并发读数据修改

3. 应用场景
  • 共享锁

    • 适用于需要读取数据且不允许其他事务修改的场景(如生成报表)。
    • 示例:
      BEGIN;
      SELECT * FROM orders WHERE user_id = 100 LOCK IN SHARE MODE;
      -- 其他事务可读,但不可修改该行
      COMMIT;
      
  • 排他锁

    • 适用于需要修改数据且禁止其他事务读写的场景(如更新账户余额)。
    • 示例:
      BEGIN;
      SELECT * FROM accounts WHERE id = 5 FOR UPDATE;
      UPDATE accounts SET balance = balance - 100 WHERE id = 5;
      COMMIT;
      

4. 锁的粒度
  • 行级锁(InnoDB支持)
    • 仅锁定目标行,其他行不受影响,并发性能高。
  • 表级锁(MyISAM默认)
    • 锁定整个表,并发性能低,但实现简单。

5. 事务隔离级别的影响
  • 读未提交(Read Uncommitted)
    • 无锁机制,可能导致脏读。
  • 读已提交(Read Committed)
    • 排他锁仅在修改时持有,提交后释放。
  • 可重复读(Repeatable Read)
    • InnoDB默认级别,通过间隙锁+临键锁防止幻读,共享锁和排他锁范围扩大至间隙。
  • 串行化(Serializable)
    • 所有SELECT隐式加共享锁,写操作加排他锁,强制事务串行。

6. 死锁与处理
  • 死锁场景
    事务A持有行1的共享锁并等待行2的排他锁,事务B持有行2的共享锁并等待行1的排他锁。
  • 解决方案
    • MySQL自动检测死锁,回滚代价较小的事务。
    • 优化事务逻辑,减少锁占用时间;按固定顺序访问资源。

7. 注意事项
  1. 显式锁与隐式锁
    • 显式锁需手动通过 LOCK IN SHARE MODEFOR UPDATE 加锁。
    • 隐式锁由DML语句(如 INSERTUPDATE)自动加锁。
  2. 锁释放时机
    • 事务提交或回滚时释放所有锁。
    • 避免长事务占用锁,影响并发性能。
  3. 存储引擎差异
    • InnoDB支持行级锁和MVCC,适合高并发。
    • MyISAM仅支持表级锁,适合读多写少场景。

8. 性能优化建议
  • 减少锁持有时间:事务尽量简短,避免在事务内执行耗时操作。
  • 合理选择隔离级别:根据业务需求调整,如非必要避免使用串行化。
  • 使用覆盖索引:减少锁的范围,避免全表扫描。
  • 监控锁争用:通过 SHOW ENGINE INNODB STATUS 分析锁冲突。

总结

共享锁和排他锁是MySQL实现并发控制的核心机制:

  • 共享锁确保读一致性,允许多读并行。
  • 排他锁确保写安全,强制串行修改。
    结合事务隔离级别和存储引擎特性,合理使用锁机制可平衡数据一致性与系统性能。

http://www.niftyadmin.cn/n/5862752.html

相关文章

如何保证bug在改完之后不会引起新bug

一、测试前:影响范围分析 代码关联分析:依据开发代码关联性检查获取改动信息,聚焦影响范围,明确代码改动影响的业务功能、是否涉及公共组件或接口,检查 Swagger 文档更新情况。若开发无法明确影响范围,在测…

算法-哈希表篇08-四数之和

四数之和 力扣题目链接 题目描述 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复&…

Python 循环中的隐藏宝藏:Else 子句深度剖析

在 Python 编程里,循环结构是基础且高频使用的部分,不过其中的 else 子句却常被大家忽略。本文将深入、全面地解析 Python 循环中 else 子句的工作原理、使用方法,通过丰富的代码示例、直观的图表,以及与其他相关知识点的对比&…

简讯:Rust 2024 edition and v1.85.0 已发布

详见 https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html 升级方法:rustup update stable

51c大模型~合集69

我自己的原文哦~ https://blog.51cto.com/whaosoft/12221979 #7项基于SAM万物分割模型研究工作 1、CC-SAM: SAM with Cross-feature Attention and Context for Ultrasound Image Segmentation #ECCV2024 #SAM #图像分割 #医学图像 Segment Anything Model (SAM) 在自…

算法:选择排序(以排队为例)

举个栗子🌰:体育课排队 假设体育老师要按身高从高到矮给10个同学排队(降序排序),老师会这样做: 第1轮:找全班最高的同学,让他站在第1个位置第2轮:在剩下的9人中找最高的…

使用Hardhat实现ERC20 代币合约详解

ERC20 代币合约详解 💰 1. 合约概览 // SPDX-License-Identifier: MIT pragma solidity ^0.8.20;import "openzeppelin/contracts/token/ERC20/ERC20.sol";contract MyToken is ERC20 {constructor() ERC20("MyToken", "MTK") {_min…

【进阶】redis篇

redis是什么 nosql not only sql(不仅仅是sql) 泛指非关系型数据库 一般把非关系型数据库称为nosql数据库. redis mongodb redis是一个nosql类型的数据库(非关系型数据库),数据在内存中以键值对形式存储. 读写速度快,也提供数据持久化方式. 一般最常用的场景就是把redis用…