2017-02-06 8 views
0

Postgresのトランザクションデータストアとして参照のない単純なフラットテーブルを使用する予定です。テーブルは常に異なるスレッドから更新されています。テーブルから最大4行の最小1行を選択し、ロックし、ステータスフィールドを更新してロックを解除する必要があります。理想的には、これは、同時クエリがお互いをブロックしていない方法である必要があります。すべてのクエリが独自の行セットを変更できます。Postgresで行レベルのロックを使用してテーブル内のランダムな4行を更新するには?

SELECT user_id FROM rooms LIMIT 1 INTO local_user_id 
WHERE user_status=0 FOR UPDATE; 

UPDATE rooms SET user_status = 1 
WHERE user_id = local_user_id; 

は、しかし、私はドロップだろう1つのトランザクションにすべて最大4人のユーザーを束ねる、一度に1-4ユーザーを更新する必要があります。

は、ドキュメントを読んだ後、私は私がそれを行うことができると思いますトランザクションの数は、4分の1のベストケースになります(4ユーザーの選択結果の大部分を仮定します)。 Postgres 9.6でこれを解決する慣用的な方法は何ですか?

UPDATE1:私はここで達成しようとしています何

は行動のようなキューである他のスレッドが喜ん行とプロセス、他の4行の残りの部分から読み取ることができますが、各スレッドは、いくつかの項目を取得し、それらを処理並行して並行して実行されます。

WITH x AS (
     SELECT user_id 
     FROM rooms 
     WHERE user_status=0 
     ORDER BY random() 
     LIMIT 4 
      FOR UPDATE 
) 
SELECT array_agg(user_id) FROM x; 

をそして1つのクエリまたは個別でその更新後:

+0

「LIMIT 4」の書き方は何ですか?それは4つ以下の結果行を与えます。 –

+0

4つのIDをどのように反復処理できますか? – Istvan

+0

お気に入りのプログラミング言語(または[PL/pgSQL](https://www.postgresql.org/docs/current/static/plpgsql.html)や[PL/Perl](https:// www .postgresql.org/docs/current/static/plperl.html)を参照してください)。 –

答えて

1

あなたは、アレイで選択されたIDを保存することができます。

+0

または単に 'select array_agg()'を 'update ... set ...に置き換えてください。ここでidは(xからuser_idを選択してください)' –

+0

です。ロックが必要ですか? –

+0

ありがとうローマ、私がここで達成しようとしているのは:他の読者が4行にアクセスするのをブロックすることです。時間がかかる操作をしていますが、各スレッドに異なる行セットを返すクエリを実行できます。私は4つのスレッドよりも一致する16の行を持っている場合は、同時並行して4行ずつ処理します。 – Istvan

関連する問題