一级:加X锁(修改)直到事务结束 → 防止丢失修改”描述的是数据库并发控制中两阶段封锁协议(2PL)下的一级封锁协议(也称基本封锁协议),其核心要点如下:
✅ 一级封锁协议定义:
事务在修改数据(即执行 WRITE(X) 操作)前,必须对数据项 X 加排他锁(Exclusive Lock, X锁);该 X 锁必须持续到事务结束(COMMIT 或 ROLLBACK),即不能提前释放。
✅ 目的与效果:
- 保证写-写冲突被串行化,从而防止丢失修改(Lost Update)。
- 例如:T1 和 T2 同时读取同一数据项后各自修改并写回,若无 X 锁保护,T2 的写入可能覆盖 T1 的结果 → 丢失修改;而一级封锁协议强制 T2 必须等待 T1 释放 X 锁后才能修改,实现顺序执行。
⚠️ 注意:
- 一级封锁协议不加锁读操作(READ),因此无法防止不可重复读和幻读;
- 它仅解决“丢失修改”,是三级封锁协议中最弱的一级;
- 它满足**两阶段封锁(增长段→收缩段)**的基本要求(X锁持至事务结束,即严格2PL的一种形式)。
典型流程示例:
T1: LOCK-X(A) → READ(A) → MODIFY(A) → WRITE(A) → UNLOCK(A) → COMMIT
T2: LOCK-X(A) → ... (必须等待T1释放锁)
一级封锁协议仅要求对修改(WRITE)操作加X锁并持至事务结束,但对读(READ)操作不加任何锁(即不加S锁或X锁)。这直接导致其无法防止不可重复读(Non-repeatable Read),原因如下:
🔹 不可重复读的定义:
同一事务中,两次读取同一数据项,得到不同值。通常由其他事务在两次读之间修改并提交了该数据项所致。
🔹 一级协议的缺陷分析(结合实例):
假设事务 T1 执行两次读取 A,事务 T2 修改 A 并提交:
T1: READ(A) → 读到 A=100
T2: LOCK-X(A) → WRITE(A=200) → COMMIT → UNLOCK-X(A)
T1: READ(A) → 读到 A=200(与第一次不同!)
- T1 在两次
READ(A)前未加S锁(一级协议不要求),因此不阻塞 T2 的 X 锁请求; - T2 成功获取 X 锁、修改并提交,释放锁后 T1 第二次读取时看到新值;
- 由于 T1 对 A 无锁保护,其读操作是“脏读”(若T2未提交则属脏读)或“不可重复读”(T2已提交),而一级协议既不防未提交读(无S锁),也不防已提交修改(无读锁持续保护)。
✅ 结论:
读操作不加锁 → 无法阻止其他事务并发修改并提交 → 同一事务内多次读取结果可能不一致 → 不可重复读发生。
要防止不可重复读,需升级到二级封锁协议(要求读操作加S锁,且S锁至少保持到读操作结束,部分实现持至事务结束)。

5225

被折叠的 条评论
为什么被折叠?



