数据库并发控制是确保多个事务同时访问数据时数据一致性的核心技术

张开发
2026/4/14 7:34:23 15 分钟阅读

分享文章

数据库并发控制是确保多个事务同时访问数据时数据一致性的核心技术
数据库并发控制是确保多个事务同时访问数据时数据一致性的核心技术。当多个事务并发操作相同数据时如果缺乏有效管控会产生三类经典的数据不一致问题丢失修改、不可重复读和读脏数据部分场景下还会出现幻读问题。1.1 三类经典数据不一致问题1丢失修改Lost Update定义两个事务同时读取同一数据并进行修改后提交的事务覆盖了先提交事务的修改导致前者的更新丢失。典型场景事务T₁和T₂同时读取数据A的值为16T₁将A减1写回15T₂也将A减1写回15最终A的值为15实际应减少2T₁的修改被丢失危害在库存扣减、账户余额修改等场景中会直接导致数据错误造成业务损失。2不可重复读Non-Repeatable Read定义同一事务内多次读取同一数据时由于其他事务在两次读取之间修改并提交了该数据导致两次读取结果不一致。典型场景事务T₁读取A50B100计算总和为150事务T₂将B修改为200并提交T₁再次读取B得到200总和变为250与第一次计算结果不一致分类数据修改导致的内容变化数据删除导致的记录消失数据插入导致的记录增多又称“幻读”3读脏数据Dirty Read定义一个事务读取了另一个事务未提交的修改数据如果该事务后续回滚读取到的数据就是无效的“脏数据”。典型场景事务T₁将C从100修改为200尚未提交事务T₂读取到C200T₁因故回滚C恢复为100T₂读取到的200就是脏数据与实际数据不一致1.2 并发控制核心技术封锁机制封锁是实现并发控制的主要手段通过对数据对象加锁限制其他事务对该数据的操作保证事务隔离性。1基本锁类型锁类型简称功能描述排它锁Exclusive LockX锁/写锁若事务T对数据A加X锁只允许T读取和修改A其他事务不能对A加任何类型的锁直到T释放锁共享锁Share LockS锁/读锁若事务T对数据A加S锁只允许T读取A但不能修改其他事务只能对A加S锁直到T释放S锁2三级封锁协议三级封锁协议通过规定加锁和释放锁的时机逐层解决不同的并发一致性问题协议级别规则描述解决的问题不足一级封锁协议事务修改数据前必须加X锁直到事务结束提交或回滚才释放丢失修改无法防止不可重复读和读脏数据二级封锁协议在一级协议基础上读取数据前必须加S锁读完后立即释放丢失修改、读脏数据无法防止不可重复读三级封锁协议在一级协议基础上读取数据前必须加S锁直到事务结束才释放丢失修改、读脏数据、不可重复读并发度最低1.3 事务隔离级别SQL标准定义了四种事务隔离级别从低到高依次为读未提交、读已提交、可重复读和串行化不同级别对应不同的数据一致性保障和并发性能 trade-off隔离级别脏读不可重复读幻读丢失更新适用场景读未提交Read Uncommitted✅ 可能✅ 可能✅ 可能✅ 可能对一致性要求极低的统计类场景读已提交Read Committed❌ 不会✅ 可能✅ 可能✅ 可能大多数普通业务场景如电商订单可重复读Repeatable Read❌ 不会❌ 不会⚠️ 部分可能❌ 不会金融、支付等对一致性要求较高的场景串行化Serializable❌ 不会❌ 不会❌ 不会❌ 不会核心数据操作如账户余额修改注MySQL InnoDB存储引擎在可重复读级别下通过MVCC间隙锁机制基本解决了幻读问题。二、典型试题与答案解析一选择题【2022年软考真题】一级封锁协议能够防止 。①丢失修改 ②不可重复读 ③读脏数据A. ① B. ①② C. ②③ D. ③答案A解析一级封锁协议仅要求修改数据前加X锁并持有到事务结束可防止两个事务同时修改同一数据导致的丢失修改但对读操作无限制因此无法防止不可重复读和读脏数据。事务T1修改了数据并写回磁盘事务T2读取了该数据后T1因某种原因撤销此时T2读到的数据是 。A. 正确数据 B. 脏数据 C. 备份数据 D. 永久数据答案B解析T2读取到了T1未提交的修改数据而T1最终回滚导致该数据无效属于典型的读脏数据场景。同一事务内多次读取同一数据结果不一致是因为其他事务在两次读取之间修改并提交了该数据这种现象称为 。A. 丢失修改 B. 读脏数据 C. 不可重复读 D. 幻读答案C解析不可重复读的核心特征是同一事务内对同一数据的多次读取结果不同原因是其他事务的更新操作。能够同时解决丢失修改、读脏数据和不可重复读问题的封锁协议是 。A. 一级封锁协议 B. 二级封锁协议 C. 三级封锁协议 D. 都不能答案C解析三级封锁协议要求读操作加S锁并持有到事务结束防止其他事务在事务执行期间修改数据因此可以同时解决三类问题。MySQL InnoDB存储引擎默认的事务隔离级别是 。A. 读未提交 B. 读已提交 C. 可重复读 D. 串行化答案C解析InnoDB默认使用可重复读隔离级别通过MVCC和间隙锁机制在保证较高一致性的同时维持较好的并发性能。二简答题请简述丢失修改、不可重复读和读脏数据的核心区别。答案要点丢失修改两个事务同时修改同一数据后提交的覆盖先提交的核心是修改操作的冲突不可重复读同一事务内多次读取同一数据因其他事务已提交的修改导致结果不同核心是同一事务内读取结果不稳定读脏数据读取到其他事务未提交的修改数据若该事务回滚则数据无效核心是读取了未提交的临时数据什么是幻读它与不可重复读有什么区别如何解决幻读问题答案要点幻读是不可重复读的特殊场景指同一事务内多次执行相同范围查询结果集行数不同原因是其他事务插入或删除了符合条件的记录区别不可重复读针对单行数据的UPDATE操作表现为数据内容变化幻读针对范围数据的INSERT/DELETE操作表现为结果集数量变化解决方案提升隔离级别至串行化或使用间隙锁如InnoDB的Next-Key Lock机制请对比二级封锁协议和三级封锁协议的异同点。答案要点相同点都基于一级封锁协议要求修改数据前加X锁并持有到事务结束都能防止丢失修改和读脏数据不同点二级协议要求读数据前加S锁读完即释放因此无法防止不可重复读三级协议要求S锁持有到事务结束可防止不可重复读但并发性能更低三案例分析题案例背景某票务系统中两个售票窗口同时查询某航班剩余机票查询结果均为5张。窗口1卖出1张将剩余机票更新为4张窗口2也卖出1张将剩余机票更新为4张。最终该航班实际卖出2张机票但系统显示仅卖出1张剩余机票为4张。该案例中出现了哪种数据不一致问题请描述问题产生的过程。答案出现了丢失修改问题。过程如下1事务T1窗口1和T2窗口2同时读取剩余机票A52T1将A减1计算得4准备写回3T2也将A减1计算得4写回数据库4T1将4写回数据库覆盖了T2的修改5最终A4实际应为3T2的修改丢失。请至少提出两种解决该问题的技术方案并说明原理。答案要点方案1使用一级封锁协议。修改剩余机票前对数据加X锁直到事务结束才释放。T1加锁后T2需等待T1释放锁才能读取和修改避免同时修改。方案2使用乐观锁机制。为剩余机票字段添加版本号每次更新时校验版本号是否与读取时一致。若不一致则说明数据已被修改需重试。例如UPDATE ticket SET count count - 1, version version 1 WHERE id 1 AND version 读取到的版本号若影响行数为0则重试。方案3使用原子更新操作。直接执行UPDATE ticket SET count count - 1 WHERE id 1数据库保证单条UPDATE语句的原子性避免并发修改冲突。三、扩展知识并发控制进阶技术3.1 MVCC多版本并发控制MVCC是InnoDB实现可重复读的核心机制通过为每行数据保存多个历史版本使读操作无需加锁读写操作不阻塞大幅提升并发性能。事务读取数据时根据事务启动时间点读取对应版本的数据快照避免感知到其他事务的修改。3.2 死锁处理并发加锁场景下可能出现死锁即两个事务互相等待对方释放锁导致都无法继续执行。数据库通常采用等待图法检测死锁发现死锁后选择代价最小的事务回滚释放其持有的锁使其他事务能够继续执行。3.3 两段锁协议两段锁协议是保证调度可串行化的重要规则要求事务分为两个阶段扩展阶段可以申请加锁但不能释放任何锁收缩阶段可以释放锁但不能再申请任何锁遵循两段锁协议的调度一定是可串行化的能够保证并发执行结果的正确性。

更多文章