2011-01-02 14 views
1

http://www.postgresql.org/docs/8.2/interactive/explicit-locking.htmlに記載されているように、の制限はロック行の前に適用できます。 pg_try_advisory_lock上のラッパーは動作しますが動作しません。ポストグラムpg_try_advisory_lockと制限の問題

休止コードは1つの行のみをロックしています。ロックされていない行をロックする代わりに、同じコードを他のインスタンスから実行すると、すでにロックされていた最初のIDをロックしようとしています。

参照:私の知る限り理解されるようにhttp://www.flyingtealeaf.com/2010/02/17/postgresql-concurrency
lock the rows until next select postgresthis

select pg_try_advisory_lock(id), * 
from 
( 
    select id,val 
from test 
left JOIN pg_locks pgl 
     ON pgl.classid = tableoid('test') 
     AND pgl.objid = test.id 
     AND pgl.pid <> pg_backend_pid() 

    WHERE pgl.objid IS NULL 
order by id limit 1 
) t 
+1

あなたの質問は何ですか? –

+0

@ Peter上記のコードが異なる5つのシステムから同時に実行されたときに、テーブルテストに例えばidを主キーとする5行が含まれていると、各システムはsys1-> id1行、sys2-> id2行のようにロックされていない行... sys5-> id5..rows。 – kiranking

答えて

0

ご迷惑をおかけして申し訳ありません。私はラインごとに最初の参照リンクを通過している必要があります。ロックfunction.Theの休閑コードを呼び出すと、LIMIT

CREATE OR REPLACE FUNCTION tableoid(tablename TEXT) RETURNS INTEGER AS $$ 
BEGIN 
    RETURN (SELECT oid FROM pg_class WHERE relname = tablename); 
END 
$$ 
LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER; 

ザン(参照リンク#1からコピー)

select pg_try_advisory_lock(tableoid('test'),id) , * from 
(
select id,val 
from test 
LEFT JOIN pg_locks pgl 
     ON pgl.classid = tableoid('test') 
     AND pgl.objid = test.id 
     AND pgl.pid <> pg_backend_pid() 

    WHERE pgl.objid IS NULL 
order by id limit 1)f 

tableoidと機能で、最後に私の作品ながら、著者がやっていたトリックは、ただのclassidを設定されていますあなたの時間と労力のために
a_horse_with_no_nameです。

3

、あなたは諮問ロックでマークされていない最初の行のための諮問ロックを取得しようとしています。

編集:これを試した後、内側のselectのpg_try_advisory_lock()は明らかに機能していません。しかし、単にのObjIDが動作するはずです確認することで、テーブルからすべての行を除く:

 
select pg_try_advisory_lock(id), * 
from 
( 
    select id,val 
    from test 
    where id not in (select objid from pg_locks where locktype = 'advisory') 
    order by id limit 1 
) t 

編集

勧告的ロックはとしてpg_locksに表示されますが、彼らが持っている表または行についての情報を持っていることはありませんロックされています。 pg_advisory_lock()の後には、基本となるテーブルや行への接続がない番号が渡されます。

SELECT pg_advisory_lock(42)

SELECT pg_advisory_lock(id) 
FROM foo 
WHERE id = 42

は、だからあなたのclassidは決して成功しないだろう使用して参加するとまったく同じ諮問ロックを作成します。

関連する問題