2017-07-16 3 views
1

postgresのSELECT FOR UPDATE SKIP LOCKED機能を使用して、テーブルから読み込んでタスクをブロックしているユーザが互いにブロックされていないことを確認し、別のユーザが既にタスクを読み込んでいないようにしたい場合:クエリで使用されているすべてのテーブルの行をロックせずに、Postgresで 'For update skip locked'を使用する方法はありますか?

タスクを取得するために、クエリで結合が使用されています。メイン情報を含むテーブル以外の行レベルのロックを他のテーブルに持たせたくありません。サンプルクエリは以下 - 以下のクエリ今

SELECT v.someid , v.info, v.parentinfo_id, v.stage FROM task v, parentinfo pi WHERE v.stage = 'READY_TASK' 
      AND v.parentinfo_id = pi.id 
      AND pi.important_info_number = ( 
      SELECT MAX(important_info_number) FROM parentinfo) 
       ORDER BY v.id limit 200 for update skip locked; 

ユーザAは、この表の一部の200行を取得している場合、ユーザーBが200の別のセットを取得することができるはずで「テーブルの-'taskの行のみをロック行。

EDIT:行が順序付けられているようで順序を置くために最善の方法

SELECT v.someid , v.info, v.parentinfo_id, v.stage FROM task v, parentinfo pi WHERE v.stage = 'READY_TASK' 
      AND v.parentinfo_id = pi.id 
      AND pi.important_info_number = ( 
      SELECT MAX(important_info_number) FROM parentinfo) ORDER BY v.id limit 200 for update of v skip locked; 

:以下のコメントを1として、クエリに変更されるのですか?複数のユーザーがこのコマンドを呼び出すと、順序が有効になりますが、返される行の順序の尊厳を維持する必要があります。

また、これも確実に同じ選択クエリを呼び出す複数のスレッドは、行の異なるセットを取得することになるんやロックが唯一の更新コマンドのために行われていますか?

+4

[Doc](https://www.postgresql.org/docs/9.5/static/sql-select.html): "FOR lock_strength [OF table_name [、...]] [NOWAIT | SKIP LOCKED] '...特定のテーブルの名前がlocking句で指定されている場合、それらのテーブルから来る行だけがロックされ、SELECTで使用される他のテーブルは単純に通常通り読み込まれます。 – Abelisto

答えて

0

これをちょっと試してみてください。複数の選択クエリは、異なる行セットの検索を終了させます。また、order byは、得られた最終結果の順序を保証します。

関連する問題