我们已经简要讨论了第一种并发控制协议,即基于锁的协议。
现在,回想我们上次离开的地方,有两种类型的锁可用共享 S(a)和独占 X(a) 。无限制地实现这个锁系统为我们提供了基于简单锁的协议(或二进制锁),但它有其自身的缺点,它们不保证可串行化。调度可以遵循前面的规则,但可能导致不可序列化的调度。
为了保证可串行化,我们必须遵循一些关于锁定和解锁操作在每个事务中的定位的附加协议。这就是两相锁定(2-PL)的概念出现的地方,2-PL 确保可序列化。现在,让我们深入挖掘!
两相锁定 –
如果锁定和解锁可以在两个阶段完成,则交易被称为遵循两阶段锁定协议。
- 成长阶段:可能会获得对数据项的新锁,但不能释放。
- 收缩阶段:可以释放现有锁,但不能获取新锁。
注 –如果允许锁转换,则在生长阶段允许将锁升级(从 S(a) 到 X(a)),并且必须将锁降级(从 X(a) 到 S(a))处于收缩阶段。
让我们看一个实现 2-PL 的事务。
T1 | T2 | |
---|---|---|
1 | lock-S(A) | |
2 | lock-S(A) | |
3 | lock-X(B) | |
4 | ……. | …… |
5 | Unlock(A) | |
6 | Lock-X(C) | |
7 | Unlock(B) | |
8 | Unlock(A) | |
9 | Unlock(C) | |
10 | ……. | …… |
这只是一个骨架交易,展示了如何使用 2-PL 进行解锁和锁定。注意事项:
交易 T 1 :
- 生长阶段是从步骤 1-3。
- 收缩阶段来自步骤 5-7。
- 锁定点在 3
交易 T 2 :
- 生长阶段是从步骤 2-6。
- 收缩阶段来自步骤 8-9。
- 锁定点在 6
嘿,等等!
什么是锁定点?增长阶段结束的点,即当事务获得最终锁时,它需要继续其工作。现在看看时间表,你一定会明白的。
我已经说过 2-PL 确保了可串行化,但是 2-PL 仍然存在一些缺点。让我们看一下缺点:
- 级联回滚在 2-PL 下是可能的。
- 死锁和饥饿是可能的。
2-PL 中的级联回滚 –
让我们看看下面的时间表:
花点时间分析一下时间表。是的,你是对的,因为分别在第 8 行和第 12 行的T 2和 T 3中的脏读,当 T 1失败时,我们也必须回滚其他人。因此,级联回滚在 2-PL 中是可能的。我以骨架计划为例,因为它保持简单就很容易理解。当用具有许多变量的实时交易问题来解释时,它变得非常复杂。
2-PL 中的死锁 –
考虑这个简单的例子,它会很容易理解。假设我们有两个事务 T 1和 T 2 。
Schedule: Lock-X1(A) Lock-X2(B) Lock-X1(B) Lock-X2(A)
绘制优先级图,您可能会检测到循环。所以死锁在 2-PL 中也是可能的。
两阶段锁定还可以限制调度中发生的并发量,因为事务在使用项目后可能无法释放它。这可能是因为我们为了确保可串行化、无死锁和其他因素而可能在日程表上设置的协议和其他限制。这是我们为确保可序列化和其他因素而必须付出的代价,因此可以将其视为并发性和维护 ACID 属性之间的讨价还价。
上述类型的2-PL称为Basic 2PL 。总而言之,它确保了冲突可串行化,但不能防止级联回滚和死锁。此外,我们将研究另外三种类型的 2PL,Strict 2PL、Conservative 2PL 和 Rigorous 2PL。
GATE相关问题:
- GATE CS 2016-2 |第 61 题
- 门 CS 1999 |第 31 题