- カテゴリ:
FOR UPDATE¶
クエリを含むトランザクションがコミットまたは中止するまで、クエリが選択した行をロックします。
この句はハイブリッドテーブルでのみサポートされており、複数のトランザクションが同時に同じ行にアクセスしようとするトランザクションワークロードに有用です。行は更新のためにロックされます。つまり、ロックを実行したトランザクションが完全にコミットされるかロールバックされるまで、他のトランザクションはこれらの行にデータを書き込むことができません。しかし、他のトランザクションはロックされた行を読むことができ、同じテーブルの他の行を読んだり、更新したり、削除したりすることができます。
SELECT ...
FROM ...
[ ... ]
FOR UPDATE [ NOWAIT | WAIT <wait_time> ]
パラメーター¶
NOWAIT
トランザクションが選択された行を直ちにロックできない場合にエラーを返します。NOWAIT がデフォルトです。
WAIT wait_time
クエリが行レベルロックを取得するまでの最大時間(秒)を指定します。待機時間が過ぎると、クエリはエラーを返します。
制限事項¶
FOR UPDATE 句。
AUTOCOMMIT トランザクション では使用できません。
SELECT ステートメント の最後の句にする必要があります。
CTAS ステートメント では使用できません。
サブクエリ 内では使用できません。
複数テーブル(結合) または セット操作 からは選択できません。
クエリが含まれている場合は使用できません。
使用上の注意¶
ハイブリッドテーブルは READ COMMITTED 分離レベルをサポートしているため、 FOR UPDATE 句では読み取り安定性が保証されません。たとえば、 ID
という名前の単一列を持つテーブル T
に、 5
と 10
という値を持つ2つの行があるとします。
以下のクエリは、トランザクション
T1
で実行されます。SELECT * FROM T WHERE ID < 20 FOR UPDATE;
クエリは値
5
と10
を返し、その2行をロックします。別のトランザクション、
T2
は、以下の DELETE 操作を実行します。DELETE FROM T WHERE ID = 5;
トランザクション
T2
は、T1
が完了するまで(つまり、コミットするかロールバックするまで)待機する必要があります。しかし、第3のトランザクション(
T3
)は、以下の INSERT 操作を完了することができます。INSERT INTO T VALUES 12;
T1
の後続クエリは2つの値ではなく、5
、10
、12
の3つの値(行)を返します。SELECT * FROM T WHERE ID < 20;
例¶
新しいトランザクションを開き、ハイブリッドテーブル(ht
)からすべての行を選択し、トランザクションがコミットするまでそれらの行をロックします。選択した行のいくつかを更新し、トランザクションをコミットする前に別のクエリを実行します。
BEGIN;
...
SELECT * FROM ht ORDER BY c1 FOR UPDATE;
...
UPDATE ht set c1 = c1 + 10 WHERE c1 = 0;
...
SELECT ... ;
...
COMMIT;
行のロックに最大60秒の待機時間を適用します。
BEGIN;
...
SELECT * FROM ht FOR UPDATE WAIT 60;
...
COMMIT;