微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

postgresql – 如何防止Postgres中的幻像读取?

有可能阻止Phantom读取,或以其他方式锁定Postgres事务中丢失的行吗?例如,请考虑以下命令序列:

在连接1上:

CREATE TABLE weather ( city varchar(80) PRIMARY KEY );
BEGIN;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
INSERT INTO weather VALUES ('a');

同时,在连接2上:

BEGIN;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT * FROM weather WHERE city = 'a' FOR SHARE;
INSERT INTO weather VALUES ('b');

并回到连接1:

COMMIT;

再次回到连接2:

COMMIT;
SELECT * FROM weather;
-- Shows both rows

连接2上的事务似乎不可能成功,因为创建行’b’的前提条件取决于行’a’的缺失.如何防止第二个事务成功?

解决方法

在不锁定整个表的情况下执行此操作的一种方法是使用Postgresql的Advisory lock [1]机制:

-- tx 1
begin;
select pg_advisory_lock(1234);
insert/update....
commit;

-- tx 2
begin;
select pg_advisory_lock(1234);
SELECT * FROM weather WHERE city = 'a' FOR SHARE;
insert/update...
commit;

这样您就可以进行事务间通信,而正常的MVCC行为是不够的.在示例1234中是具有应用级别含义的任意整数.另请参阅[2]了解更多使用咨询锁的方法.

[1] http://www.postgresql.org/docs/9.5/static/explicit-locking.html#ADVISORY-LOCKS

[2] http://www.postgresql.org/docs/9.5/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS-TABLE

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐