3.8.1 并发控制概述
本课核心知识点整理
为什么事务要并发控制
数据库中的操作通常以事务为单位执行。现实系统不可能让所有事务严格排队串行执行,否则效率太低:一个用户转账、另一个用户查询余额、后台批处理更新库存,都可能同时发生。
并发控制的目标不是禁止并发,而是在允许事务交错执行的同时,仍然保证数据库的一致性和事务的隔离性。
mermaid
flowchart LR
A["多个事务并发执行"] --> B{"读写同一数据?"}
B -->|否| C["可安全并行"]
B -->|是| D["可能破坏隔离性"]
D --> E["丢失修改 / 不可重复读 / 读脏数据"]
E --> F["封锁协议等并发控制机制"]本节所在的小模块
字幕把事务并发控制分成三块:
| 内容 | 要解决的问题 | 软考关注度 |
|---|---|---|
| 事务特性 | 事务为什么可靠 | ACID 概念常考 |
| 并发问题 | 事务交错会出什么错 | 了解三类异常 |
| 封锁协议 | 如何限制冲突读写 | S 锁、X 锁原则更常见 |
这部分在软件设计师中整体分值不高,通常 1 到 2 分,但概念容易混淆,尤其是“持久性 vs 原子性”“不可重复读 vs 读脏数据”“S 锁 vs X 锁”。
并发控制保护的是什么
事务并发主要破坏的是隔离性,进而可能破坏一致性。比如两个事务都读取同一个库存数并分别修改,后写回的值可能覆盖前一个事务的修改;或者一个事务读取了另一个事务尚未提交、后来又回滚的数据。
| 风险 | 发生原因 | 需要的控制 |
|---|---|---|
| 写写覆盖 | 多个事务同时修改同一数据 | 写前加排他锁 |
| 读到中间状态 | 一个事务读到另一个事务未提交结果 | 限制读未提交数据 |
| 两次读不一致 | 事务读取期间其他事务修改并提交 | 读锁保持到合适时机 |
| 效率下降 | 过度串行或锁粒度过大 | 在正确性和并发度之间平衡 |
所以并发控制本质上是在“正确性”和“吞吐量”之间做制度设计:控制太弱会出错,控制太强会降低并发。
封锁是最基础的办法
封锁协议通过“读之前/写之前先申请锁”的方式限制冲突操作。软考字幕中特别强调,目前主要掌握共享锁 S 和排他锁 X 的加锁原则:
| 锁 | 又称 | 主要用途 |
|---|---|---|
| S 锁 | 共享锁、读锁 | 控制读取 |
| X 锁 | 排他锁、写锁、独占锁 | 控制修改 |
后面三级封锁协议、两段锁等都可以理解为在不同阶段要求事务持有或释放这些锁,从而防止不同并发异常。
做题路线
- 看到多个事务交错读写同一数据,先想到并发控制。
- 如果题目问事务可靠性,优先定位 ACID。
- 如果题目给读写序列,判断是写写覆盖、两次读不同,还是读到未提交数据。
- 如果题目给锁状态,按 S/X 锁兼容关系判断后续加锁是否成功。
例题
数据库并发控制的主要目的是:
数据库并发控制中常见的一种技术是:
自查要点
- 为什么数据库需要并发控制?
- 并发控制是否等于禁止并发?
- 常见并发异常有哪些?