在DBMS中使用锁进行并发控制
锁是维护DBMS中并发控制的重要部分。在实现基于锁的并发控制的任何系统中,事务在获得所需的锁之前不能读取或写入语句。
锁定协议中有两种类型的锁。它们是:
- 二元锁 – 这些只能处于两种状态中的一种,锁定或未锁定。
- 共享/独占锁 – 当只执行读操作时,会获取共享锁。由于没有数据被改动,共享锁可以在多个事务之间共享。执行写操作时会使用独占锁。只有持有独占锁的事务可以更改数据值。
不同的锁定协议是 −
阅读更多:MySQL 教程
简单锁定协议
事务在执行写操作之前获得数据值的锁定。在写操作完成后,锁定可以释放。简单锁定协议的示例如下:
T1 | T2 |
---|---|
R(A) | |
R(A) | |
Lock(B) | |
R(B) | |
W(B) | |
Unlock(B) | |
Lock(C) | |
R(C) | |
W(C) | |
Unlock(C) | |
Commit | |
Commit |
上面显示了两个交易T1和T2。读操作不需要锁定,但在写操作之前,每个交易都会获取锁定并在其后释放锁定。
两阶段锁定协议
两阶段锁定协议有两个阶段,即增长阶段和缩小阶段。当事务处于增长阶段时,它只能获取锁定。当它进入缩小阶段时,它可以释放先前获取的锁,但不能获取新的锁。独占锁由X表示,共享锁由S表示。两阶段锁定协议的示例是−
T1 | T2 |
---|---|
S(A) | |
R(A) | |
S(A) | |
R(A) | |
X(B) | |
R(B) | |
W(B) | |
X(C) | |
R(C) | |
W(C) | |
Unlock(C) | |
Unlock(A) | |
Unlock(B) | |
Unlock(A) | |
Commit | |
Commit |
在上面的示例中,T1和T2共享变量A,使用共享锁因为只执行读操作。T1通过获取B的独占锁执行写操作,并在不久后释放。T2也是同样的方式使用C。
严格的两阶段锁定协议
严格两阶段锁定协议与两阶段锁定协议类似。唯一的区别在于,在严格的二阶段锁定协议中,协议获得的所有排他锁都需要保持,直到协议提交或中止。严格的两阶段锁定协议的示例是:
T1 | T2 |
---|---|
S(A) | |
R(A) | |
S(A) | |
R(A) | |
X(B) | |
R(B) | |
W(B) | |
X(C) | |
R(C) | |
W(C) | |
Unlock(A) | |
Unlock(A) | |
Commit | |
Unlock(B) | |
Commit | |
Unlock(C) |
在上面的示例中,T1和T2共享变量A,并使用共享锁,因为只对A进行读取操作。T1获取用于写入操作的B的排他锁,T2则获取C的排他锁。只有在交易提交时,才会释放排他锁。但是,对于共享锁则没有这样的约束。
严格的两阶段锁定协议
严格的两阶段锁定协议仅是两阶段锁定协议和严格的两阶段锁定协议的扩展。在此协议中,事务持有的所有锁(无论是共享锁还是排他锁)都只在事务提交或中止时才释放。严格两阶段锁定协议的示例是:
T1 | T2 |
---|---|
S(A) | |
R(A) | |
S(A) | |
R(A) | |
X(B) | |
R(B) | |
W(B) | |
X(C) | |
R(C) | |
W(C) | |
Commit | |
Unlock(A) | |
Unlock(B) | |
Commit | |
Unlock(A) | |
Unlock(C) |
在上面的示例中,T1和T2共享变量A,并使用共享锁,因为只对A进行读取操作。T1获取用于写入操作的B的排他锁,T2则获取C的排他锁。无论是共享锁还是排他锁,在交易提交后才会释放。