数据库之并发控制

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 + 多粒度锁 来实现高并发,而非单纯依赖封锁协议。但理解封锁协议仍是理论基础。


五、记忆口诀

一级防丢失,

二级加读锁(防脏读),

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


相关推荐
+VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue校园实验室管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
warton882 小时前
proxysql配置mysql mgr代理,实现读写分离
linux·运维·数据库·mysql
Coder_Boy_2 小时前
基于SpringAI的在线考试系统-核心模块的数据模型交互关系
java·数据库·人工智能·spring boot·交互
短剑重铸之日2 小时前
7天读懂MySQL|特别篇:MVCC详解
数据库·后端·mysql·mvcc
北邮刘老师2 小时前
从SEO到ADO:智能体时代的流量密码
服务器·网络·数据库·人工智能·大模型·智能体·智能体互联网
javachen__2 小时前
mysql系统级文件损坏修复
数据库·mysql
云和数据.ChenGuang2 小时前
达梦数据库部署安装故障一
数据库·oracle·达梦·信创·达梦数据库
倔强的石头1063 小时前
场景化落地指南——金仓时序数据库在关键行业的应用实践
数据库·时序数据库·kingbase
xj7573065333 小时前
《精通Django》 第7章 高级视图和URL配置
数据库·django·sqlite