2016-04-03 15 views
5

Fantom okumalarını önlemek veya Postgres işleminde eksik bir satır kilitlemek mümkün mü? bağlantı 2,Postgres'de fantom okumaları nasıl önlenir?

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

arada:

1 bağlantısının: Örneğin, aşağıdaki komut dizisi dikkate

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

ve geri bağlantı ila 1:

COMMIT; 

Ve tekrar 2 numaralı bağlantıya geri dönün:

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

Bağlantı 2'deki işlemin başarılı olması mümkün görünmüyor, çünkü 'b' satırının oluşturulmasındaki önkoşul, satır 'a'nın yokluğuna bağlıydı. İkinci işlemin başarılı olmasını nasıl engellerim? Bütün tablo kilitlemeden bunu yapmanın

+0

PostgreSQL Versiyonu –

+0

psql (PostgreSQL) 9.3.11 –

+1

Davranışsal işlemler, davranışların * bu işlemlerin seri olarak sipariş edilmesiyle tutarlı olduğu sürece başarılı olabilir, ancak bu siparişlerin, bu işlemlerin başlatıldığı veya işlendiği sırayla bir ilgisi yoktur. . Bu durumda, eğer işlem 2'yi takiben işlem 1'i çalıştırmış olsaydınız aynı sonucu elde edersiniz, bu yüzden bir anlaşmazlık için herhangi bir sebep göremiyorum. –

cevap

0

bir yolu PostgreSQL en Advisory lock [1] mekanizma kullanıyor:

-- 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; 

normal MVCC davranışı yeterli değildir arası işlem iletişimi, yapabilir Bu şekilde. Örnek 1234 uygulama düzeyinde bir anlam ile keyfi tamsayıdır. Ayrıca danışma kilitleriyle çalışmak için daha fazla yol görmek için [2] 'ye bakın.

[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