ソフトウェア開発者の日常

こだわりなく書きたいことを書いていきます。

PostgreSQLでレコードロックをして更新する方法

昨日テーブルをロックして更新する方法を書きました。
PostgreSQLでテーブルロックをして更新する方法 - ソフトウェア開発者の日常

テーブル全体をロックすると、条件によっては同時に処理できるのが、テーブルのロックを獲得できるまで待機することになります。
レコードのロックにすれば、条件によっては同時に処理できるはずなので、レコードをロックする方法を確認したところ、以下のコードで出来ました。

BEGIN;
SELECT id FROM table1 WHERE type = 1 ORDER BY id LIMIT 2 FOR UPDATE;
UPDATE table1 SET updatetime = now() WHERE id IN (2,3);
COMMIT;

PostgreSQLのマニュアルの行レベルロックの説明には

 行レベルロックは、データの問い合わせには影響を与えません。 行レベルロックは、<i>同じ行に対する書き込みだけを</i>ブロックします。

とあって、SELECTはブロックされないと読み取れました。
続いて、

実際に行を変更せずに行に対して行レベルロックを獲得するには、該当する行をSELECT FOR UPDATEで選択してください。

とあるので、SELECTはブロックされるようで、実際試したら、ブロックされていました。

自動でロックされる場合のことも交えて書いてあるようなので、こういう記述なんでしょうね。