10

postgres のアドバイザリー ロックについて、私が理解していない基本的なことがあるに違いないと思います。psql コマンド ライン クライアントで次のコマンドを入力すると、関数は両方とも true を返します。

SELECT pg_try_advisory_lock(20); --> true
SELECT pg_try_advisory_lock(20); --> true

ロックは既に取得されているはずなので、2 番目のコマンドは false を返すはずだと思っていました。奇妙なことに、ロックが2回取得されたことを示唆する次の結果が得られます。

SELECT pg_advisory_unlock(20); --> true
SELECT pg_advisory_unlock(20); --> true
SELECT pg_advisory_unlock(20); --> false

私の質問は、アドバイザリ ロックを取得して再度取得されないようにするにはどうすればよいかということだと思います。

4

2 に答える 2

16

2 つの異なる PostgreSQL セッションからこれを試してみるとどうなりますか?

ドキュメントで詳細を確認してください。

于 2012-04-23T14:57:46.017 に答える
3

アドバイザリ ロックに対する私の第一印象は似ていました。2 番目のクエリ (SELECT pg_tryadvisory_lock(20)) も false を返すと予想していました (最初のクエリがロックを取得したため)。しかし、このクエリは、値が 20 の bigInt にロックがあることを確認しただけです。解釈はユーザー次第です。

アドバイザリ ロックを、値を格納してその値 (通常は BigInt) のロックを取得できるテーブルと想像してください。明示的なロックではなく、トランザクションが遅延することはありません。結果をどのように解釈して使用するかはあなた次第です - そしてそれはブロッキングではありません。

プロジェクトで two-integers-options を使用して使用します。SELECT pg_try_advisory_lock(classId, objId) に対して、両方のパラメータは整数です。

複数のテーブルで動作させるには、テーブルの OID を classId として使用し、プライマリ ID (ここでは 17) を objId として使用します。

SELECT pg_try_advisory_lock((SELECT 'first_table'::regclass::oid)::integer, 17);

この例では、「first_table」はテーブルの名前で、2 番目の整数は主キー ID (ここでは 17) です。

パラメーターとして bigInt を使用すると、より広い範囲の ID が可能になりますが、「second_table」と共に使用すると、ID 17 もロックされます (テーブル内の特定の行との関係ではなく、数値「17」をロックしたため)。 .

それを理解するのに少し時間がかかったので、アドバイザリ ロックの内部動作を理解するのに役立つことを願っています。

于 2015-09-11T18:31:33.653 に答える