锁是维护DBMS中并发控制不可或缺的一部分。任何实现基于锁的并发控制的系统中的事务,在获得所需的锁之前都无法读取或写入语句。
基于锁的协议中有两种类型的锁。这些是:
二进制锁- 只能处于以下两种状态之一:锁定或解锁。
共享/独占锁- 仅执行读取操作时,将获取共享锁。共享锁可以在多个事务之间共享,因为没有数据被更改。执行写操作时,将使用排他锁。只有持有排他锁的事务才允许更改数据值。
不同的锁定协议是-
在执行写操作之前,通过事务获得对数据值的锁定。写操作之后,可以释放锁。简单锁定协议的一个示例是:
T1 | T2 |
---|---|
R(A) | |
R(A) | |
锁(B) | |
R(B) | |
宽(宽) | |
解锁(B) | |
锁(C) | |
R(C) | |
厕所) | |
解锁(C) | |
承诺 | |
承诺 |
上面显示了两个事务T1和T2。读操作不需要锁,但是在写操作之前,这些事务中的每一个都获取一个锁,然后将其释放。
两阶段锁定协议有两个阶段,即增长阶段和收缩阶段。事务仅在增长阶段才能获得锁。当它进入收缩阶段时,它可以释放以前获取的锁,但不能获取新的锁。互斥锁由X表示,共享锁由S表示。两阶段锁定协议的示例为-
T1 | T2 |
---|---|
S(A) | |
R(A) | |
S(A) | |
R(A) | |
X(B) | |
R(B) | |
宽(宽) | |
X(C) | |
R(C) | |
厕所) | |
解锁(C) | |
解锁(A) | |
解锁(B) | |
解锁(A) | |
承诺 | |
承诺 |
在上面的示例中,T1和T2使用共享锁共享变量A,因为仅对A执行读操作。T1在B上获取写操作的互斥锁,然后立即释放它。T2与C相同。
严格的两阶段锁定协议类似于两阶段锁定协议。唯一的区别是,在严格的2PL协议中,必须保留协议获得的所有排他锁,直到协议提交或中止。严格的两阶段锁定协议的一个示例是:
T1 | T2 |
---|---|
S(A) | |
R(A) | |
S(A) | |
R(A) | |
X(B) | |
R(B) | |
宽(宽) | |
X(C) | |
R(C) | |
厕所) | |
解锁(A) | |
解锁(A) | |
承诺 | |
解锁(B) | |
承诺 | |
解锁(C) |
在上面的示例中,T1和T2使用共享锁共享变量A,因为仅对A执行读操作。T1在B上获取写操作的互斥锁,而T2对C执行此操作。仅释放互斥锁事务完成后。但是,共享锁没有这种限制。
严格的两阶段锁定协议仅仅是两阶段锁定协议和严格的两阶段锁定协议的扩展。在这里,仅在事务提交或中止后才释放事务持有的所有锁(无论是共享锁还是独占锁)。严格的两阶段锁定协议的一个示例是:
T1 | T2 |
---|---|
S(A) | |
R(A) | |
S(A) | |
R(A) | |
X(B) | |
R(B) | |
宽(宽) | |
X(C) | |
R(C) | |
厕所) | |
承诺 | |
解锁(A) | |
解锁(B) | |
承诺 | |
解锁(A) | |
解锁(C) |
在上面的示例中,T1和T2使用共享锁共享变量A,因为仅对A执行读操作。T1在B上获取写操作的互斥锁,而T2对C执行相同操作。仅在事务提交后才释放排他锁。