Two-phase locking (2PL) is a concurrency controlprotocol that determines whether a txn can access an object in the database on the fly.
The protocol does not need to know all the queriesthat a txn will execute ahead of time.
分为两个阶段:
一阶段:只能加锁:Growing
二阶段:只能解锁:Shrinking
二阶段锁可以保证冲突可串行化。
1. 但是存在级联回滚的问题。
T2在T1的临时版本上做了操作,所以导致回滚。所以可以在最后commit 之前再解锁:
Strong Strict 2PL
只有在commit之前才一次性全部解锁。 不会产生级联回滚。其实也就是解决了脏读的问题,级联回滚的的原因就是产生了脏读。
2. 二阶段锁可能出现死锁的问题。
两种方法:
死锁检测:
构建了一个锁的等待图,节点是事务,边是等待锁。如果存在环路,那么就存在死锁。
victim selection 牺牲者选择方法:
通过其运行时间;运行语句数量;有多少锁被锁;必须要回滚的语句次数;已经回滚的次数;
同时,也不需要全部回滚。
死锁预防:
给每个事务一个优先级,老的事务优先级比较高;
wait-die;
老的等年轻的释放锁,年轻的如果要获取老的锁,就直接终止;
wound-wait:
老的直接获取新的锁,直接抢夺;新的需要等老的锁。
如果新的被中止后,它的时间戳是一开始执行的时间。
锁的粒度也需要权衡
粒度越小,并行越好,但是加锁的消耗就更大了。这里就需要一个权衡。
Intention Locks
意向标记,如果行被锁了,那么表就会有一个意向标记,这样其他事务在给表加锁的时候,就不需要逐个遍历行是否有锁了。
An intention lock allows a higher-level node tobe locked in shared or exclusive mode without having to check all descendent nodes.
所以构建了一个新的矩阵: