two-phase locking

two-phase locking(2pl)是指在一个事务分成两个阶段:

1. 第1阶段只能加锁

2. 第2阶段只能释放锁

它的反面就是: 对A加锁,然后释放; 再加B锁,再释放。。。

后面这种方式保证不了serializability.   比如,

事务甲               事务乙

———————-

对A加写锁

set A=100

对A释放写锁

                      对A加写锁

                      set A=200

                      对A释放写锁

对A加读锁

对B加写锁

set B=A*2=…

select B

对A释放读锁    

对B释放写锁

             

———————-

事务甲结束后,B的值变成了400; 而我们本来预期这个值应该是200的 (没有满足repeatable read这个级别)

要解决这个问题,可以干脆等事务甲全部结束再执行事务乙;既然事务之间是通过锁来协调的,可以让事务甲的锁全部释放了,再让事务乙获得锁,以保证一致性。

事务甲               事务乙

———————-

对A加写锁

set A=100

                      对A加写锁

                      等待。。。。

对B加写锁

set B=A*2=…                 

select B

对A释放读锁

                      set A=200

                      对A释放写锁

对B释放写锁 

———————-

事务甲结束后,B的值变成了200,符合预期。这时事务甲用的就是2pl, 释放第一个锁后不再加任何锁。

2pl有个缺点:事务有多久,一个锁就会持续多久,即使你加的是读锁。结合 MVCC机制(Multi-Version Concurrency Control)情况可以好一点,MVCC并没有否定2pl,只不过在读时它并不加锁。

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.