web-dev-qa-db-ja.com

「更新の選択」はいつロックおよびロック解除されますか?

これが私の擬似コードです:

re = [select **result** from table where **condition**=key for update]

if[re satisfies]
{
    delete from table where **condition** = key;
}

commit

「キー」と等しい条件の行がすでに削除されているかどうかを確認したいのですが、「更新の選択」によってブロックされたロックを自動的にロック解除できますか。つまり、この時点で別のプロセスが入力され、同じ「キー」を選択した場合です。 「これでブロックできないの?

18
venus.w

ロックは、コマンドの実行中(通常は最初またはその近く)に取得されます。ロック( アドバイザリロック を除く)は、トランザクションがコミットまたはロールバックされたときに解放されますのみFOR UNLOCKはなく、テーブルレベルのUNLOCKコマンドの効果を元に戻すためのLOCKコマンドもありません。これはすべて説明されています PostgreSQLドキュメントの同時実行制御セクションで

ロックを解除するには、トランザクションをコミットまたはロールバックする必要があります。

さらに、「この行は別の同時トランザクションによってすでに削除されているか」と尋ねるのはあまり意味がありません。行を削除したトランザクションがコミットするまで、実際には削除されません...それでも、行を削除して再挿入したか、別の並行トランザクションが行を再度挿入した可能性があります。

万が一、タスクキューまたはメッセージキューシステムを構築していますか。そうすれば、その問題は解決され、その異常に複雑なホイールを再発明しようとすべきではないからです。 [〜#〜] pgq [〜#〜]ActiveMQRabbitMQZeroMQ などを参照してください(将来のPostgreSQLバージョン これはテスト中であるため、FOR UPDATE SKIP LOCKED が含まれる可能性がありますが、執筆時点ではリリースされていません)。

解決しようとしている根本的な問題のより詳細な説明を含む新しい質問を投稿することをお勧めします。問題の解決策は、「行がすでに削除されているかどうかを確認する」または「行のロックを解除する」ことであると想定しています。それはおそらく実際には解決策ではありません。プッシュバイクが動かないときに「ガソリンはどこで買えばいいの?」と言う人がいるので、燃料がなくなったと思っているようなものです。燃料は問題ではありません。問題は、プッシュバイクが燃料を受け取らないため、ペダルを漕ぐ必要があることです。

背景を説明してください。達成しようとしていることを説明してください。何よりも、擬似コードを投稿しないでください。投稿問題が発生している実際のコード、できれば自己完結型で実行可能な形式で投稿してください。

23
Craig Ringer