PostgreSQL从8.2版本就开始支持advisory lock这一功能。那么什么是advisory lock呢?官方文档的解释是:
PostgreSQL提供了一种方法创建由应用定义其含义的锁。这种锁被称为咨询锁,因为系统并不强迫其使用——而是由应用来保证其正确的使用。
advisory lock分为会话级别和事务级别两种(9.1版本加入事务级别)。事务级别的advisory lock不能显性的释放。advisory lock和系统的MVCC不是一个概念,基本上完全不相干。锁的数量由 max_locks_per_transaction and max_connections 决定。
advisory lock相关的函数:
advisory lock 不受事务的影响,在同一个会话中 advisory lock 可以多次lock,但是必须与unlock成对使用。
可能看了上面的解释你还是会有些云里雾里的感觉,那么我们就看看advisory lock究竟能用在哪些场景下吧!
–场景1
两个会话,同时对同一个ID值的记录执行删除后插入,有一个会话会出现删除0,插入失败的现象。
建表:
bill@bill=>CREATE TABLE test (id INT PRIMARY KEY);
CREATE TABLE
bill@bill=>INSERT INTO TEST VALUES (1);
INSERT 0 1
bill@bill=>INSERT INTO TEST VALUES (2);
INSERT 0 1
分别在两个会话中执行下列语句:
begin;
1:DELETE FROM test WHERE id=1;
2:INSERT INTO test VALUES (1);
3:COMMIT;
有点经验的人可能立刻就会发现:在会话二中会因为会话一产生锁等待,直到会话一结束就可以执行自己会话中的语句了。事实真的如此吗?
会话一:
bill@bill=>begin;
BEGIN
bill@bill=>DELETE FROM test WHERE id=1;
DELETE 1
bill@bill=>INSERT INTO test VALUES (1