カテゴリ:

クエリ構文

FOR UPDATE

クエリを含むトランザクションがコミットまたは中止するまで、クエリが選択した行をロックします。

この句はハイブリッドテーブルでのみサポートされており、複数のトランザクションが同時に同じ行にアクセスしようとするトランザクションワークロードに有用です。行は更新のためにロックされます。つまり、ロックを実行したトランザクションが完全にコミットされるかロールバックされるまで、他のトランザクションはこれらの行にデータを書き込むことができません。しかし、他のトランザクションはロックされた行を読むことができ、同じテーブルの他の行を読んだり、更新したり、削除したりすることができます。

SELECT ...
  FROM ...
  [ ... ]
  FOR UPDATE [ NOWAIT | WAIT <wait_time> ]
Copy

パラメーター

NOWAIT

トランザクションが選択された行を直ちにロックできない場合にエラーを返します。NOWAIT がデフォルトです。

WAIT wait_time

クエリが行レベルロックを取得するまでの最大時間(秒)を指定します。待機時間が過ぎると、クエリはエラーを返します。

制限事項

FOR UPDATE 句。

使用上の注意

ハイブリッドテーブルは READ COMMITTED 分離レベルをサポートしているため、 FOR UPDATE 句では読み取り安定性が保証されません。たとえば、 ID という名前の単一列を持つテーブル T に、 510 という値を持つ2つの行があるとします。

  1. 以下のクエリは、トランザクション T1 で実行されます。

    SELECT * FROM T WHERE ID < 20 FOR UPDATE;
    
    Copy

    クエリは値 510 を返し、その2行をロックします。

  2. 別のトランザクション、 T2 は、以下の DELETE 操作を実行します。

    DELETE FROM T WHERE ID = 5;
    
    Copy

    トランザクション T2 は、 T1 が完了するまで(つまり、コミットするかロールバックするまで)待機する必要があります。

  3. しかし、第3のトランザクション(T3)は、以下の INSERT 操作を完了することができます。

    INSERT INTO T VALUES 12;
    
    Copy
  4. T1 の後続クエリは2つの値ではなく、 51012 の3つの値(行)を返します。

    SELECT * FROM T WHERE ID < 20;
    
    Copy

新しいトランザクションを開き、ハイブリッドテーブル(ht)からすべての行を選択し、トランザクションがコミットするまでそれらの行をロックします。選択した行のいくつかを更新し、トランザクションをコミットする前に別のクエリを実行します。

BEGIN;
...
SELECT * FROM ht ORDER BY c1 FOR UPDATE;
...
UPDATE ht set c1 = c1 + 10 WHERE c1 = 0;
...
SELECT ... ;
...
COMMIT;
Copy

行のロックに最大60秒の待機時間を適用します。

BEGIN;
...
SELECT * FROM ht FOR UPDATE WAIT 60;
...
COMMIT;
Copy