数据库之并发控制

1.事务

事务:由一系列操作组成,这些操作,要么全做,要么全不做,拥有四种特

性,详解如下:

  • (操作) 原子性:要么全做,要么全不做
  • (数据)一致性:事务发生后数据是一致的,例如银行转账,不会存在A账户转
    出,但是B账户没收到的情况。
  • (执行)隔离性:任一事务的更新操作直到其成功提交的整个过程对其他事务
    都是不可见的,不同事务之间是隔离的,互不干涉。
  • (改变)持久性:事务操作的结果是持续性的。

事务是并发控制的前提条件,并发控制就是控制不同的事务并发执行,提高

系统效率,但是并发控制中存在下面三个问题:

  • 丢失更新:事务1对数据A进行了修改并写回,事务2也对A进行了修改并写回

    此时事务2写回的数据会覆盖事务1写回的数据,就丢失了事务1对A的更新。即

    对数据A的更新会被覆盖。

  • 不可重复读:事务2读A,而后事务1对数据A进行了修改并写回,此时若事务2

    再读A,发现数据不对。即一个事务重复读A两次,会发现数据A有误。

  • 读脏数据:事务1对数据A进行了修改后,事务2读数据A,而后事务1回滚,数

    据A恢复了原来的值,那么事务2对数据A做的事是无效的,读到了脏数据。

2.封锁协议

你对 X锁(排他锁) 、S锁(共享锁) 以及三级封锁协议 的理解基本正确,但为了更准确、系统地掌握并发控制中的封锁机制,下面我将为你全面梳理并补充细节,包括三级封锁协议的具体内容、各自能解决的问题,以及它们之间的区别。


一、锁的基本类型

锁类型 名称 允许操作 其他事务能否加锁?
S锁 共享锁(Shared Lock / Read Lock) 只读 可以加 S锁 ,不能加 X锁
X锁 排他锁(Exclusive Lock / Write Lock) 读 + 写 不能加任何锁(S 或 X)

✅ 你的描述正确:

  • X锁:独占,其他事务完全不能访问(读/写都不行);
  • S锁:允许多个事务同时读,但禁止写。

二、三级封锁协议(Three-Level Locking Protocols)

这三级协议通过规定何时加锁、何时释放锁,来防止并发异常。级别越高,一致性越强,但并发性越低。


一级封锁协议
  • 规则 :
    事务在修改数据 R 之前 ,必须先对其加 X锁 ,并且直到事务结束(COMMIT 或 ROLLBACK)才释放。
  • 可解决的问题 :✅ 丢失更新(Lost Update)
  • 不能解决的问题:❌ 脏读、❌ 不可重复读
  • 说明 :
    因为写操作被 X 锁保护到事务结束,所以两个事务不能同时写同一数据,避免了覆盖。

📌 注意:一级协议不要求对"读操作"加锁,所以仍可能读到未提交的数据(脏读)。


二级封锁协议
  • 规则 :
    • 在一级的基础上,事务在读取数据 R 之前 ,必须先加 S锁;
    • S锁在读完后即可释放(不需要等到事务结束)。
  • 可解决的问题 :✅ 丢失更新 + ✅ 脏读(Dirty Read)
  • 不能解决的问题:❌ 不可重复读
  • 说明 :
    因为读的时候加了 S 锁,阻止了其他事务在此期间对 R 加 X 锁并修改(若对方要写,需等你读完),所以不会读到"正在被修改但未提交"的数据 → 避免脏读。
    但 S 锁很快释放,后续其他事务仍可修改 R,导致本事务再次读时值变了 → 仍存在不可重复读。

三级封锁协议
  • 规则 :
    • 在二级的基础上,S锁必须保持到事务结束才释放(不只是读完就放)。
  • 可解决的问题 :✅ 丢失更新 + ✅ 脏读 + ✅ 不可重复读
  • 不能解决的问题 :❌ 幻读(Phantom Read)(严格来说,封锁协议主要针对已存在的元组,幻读涉及新插入的行)
  • 说明 :
    由于 S 锁一直持有到事务结束,其他事务在整个过程中都无法修改该数据 → 同一事务内多次读取结果一致。

🔔 注意 :三级封锁协议并未直接解决幻读 。要完全避免幻读,通常需要范围锁(Range Lock) 或采用 Serializable 隔离级别(如使用谓词锁或串行执行)。


三、总结对比表

封锁协议 读操作加锁? 写操作加锁? 锁释放时机 解决的问题
一级 ❌ 不要求 ✅ 必须加 X 锁 X 锁:事务结束 丢失更新
二级 ✅ 加 S 锁 ✅ 加 X 锁 S 锁:读完即放X 锁:事务结束 丢失更新、脏读
三级 ✅ 加 S 锁 ✅ 加 X 锁 S 锁 & X 锁:都到事务结束 丢失更新、脏读、不可重复读

四、补充说明

  1. 两段锁协议(2PL) vs 三级封锁协议

    • 三级封锁协议是针对特定异常设计的规则;
    • 两段锁协议 (Growing Phase + Shrinking Phase)是保证可串行化调度的充分条件,与三级协议目的不同,但三级协议通常满足 2PL。
  2. 实际数据库实现

    现代数据库(如 MySQL InnoDB)更多采用 MVCC + 多粒度锁 来实现高并发,而非单纯依赖封锁协议。但理解封锁协议仍是理论基础。


五、记忆口诀

一级防丢失,

二级加读锁(防脏读),

三级锁到底(防不可重复读)。


相关推荐
CoLiuRs5 小时前
电商价格是怎样算出来的
数据库·redis·缓存
小蒜学长5 小时前
基于Python的动物救助站管理系统的设计与实现(代码+数据库+LW)
数据库·后端·python·django·动物救助
weixin_404551246 小时前
自动化数据库理解:用 AI 与 LLM 自动推断表的用途与关系
数据库·人工智能·自动化
java1234_小锋6 小时前
【技术专题】Mysql8 数据库 - Mysql8 简介 & 安装以及配置
数据库·mysql
oradh6 小时前
Oracle固定执行计划的方法----SQL Profie(三)
数据库·sql·oracle
测试学习test7 小时前
SPI读取W25Q64硬件驱动(HAL库)
数据库·stm32·嵌入式硬件·算法
做运维的阿瑞7 小时前
mysql数据库分组查询:GROUP BY 与 HAVING 的执行逻辑
数据库·sql·mysql
LaughingZhu8 小时前
Product Hunt 每日热榜 | 2026-10-01
数据库·人工智能·深度学习·神经网络·搜索引擎
阳光九叶草LXGZXJ8 小时前
达梦数据库-学习-67-SSL加密认证
linux·运维·数据库·sql·学习·ssl
ha_lydms8 小时前
MaxCompute中JSON函数
大数据·数据库·阿里云·json·dataworks·maxcompute·odps