UPDATEステートメントが実行された後、ステートメントの効果は残りのトランザクション(およびコミットした場合、他のトランザクション)に表示されます。オラクルが実際にどのような順序で実行するかは、の実装の詳細です(同様に、ORDER BYを指定する場合はを指定しない限り、SELECT結果の順序は保証されません)。
ほとんどの場合、この順序はクライアントには関係ありません。重複する行のセットを更新している別のトランザクションでデッドロックを回避する場合があります。 UPDATEは、トランザクションが終了するまで更新される行をロックします。したがって、2つのトランザクションが同じ行をロックしようとしたときに異なる順序でロックしようとすると、デッドロックが発生する可能性があります。
デッドロックを回避する標準的な方法は、常に明確な順序でロックすることです。残念ながら、UPDATEは、ORDER BY句を持っていませんが、あなたはこれを行うことができます。condition
は両方のステートメントでも同じです
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT ... WHERE condition ORDER BY ... FOR UPDATE;
UPDATE ... WHERE condition;
COMMIT;
を。 WHERE
が常に両方のステートメントの同じ行セットを参照するには、直列化可能な分離レベルが必要です。
あるいは、PL/SQLであなたはこのような何か行うことができます:
DECLARE
CURSOR CUR IS SELECT * FROM YOUR_TABLE WHERE condition ORDER BY ... FOR UPDATE;
BEGIN
FOR LOCKED_ROW IN CUR LOOP
UPDATE YOUR_TABLE SET ... WHERE CURRENT OF CUR;
END LOOP;
END;
/
論理的に、彼らは同時に発生します。実際には、彼らはしませんが、あなたは違いを見つけることができなくなります。あなたが 'UPDATE Table1 SET Index = Index + 1 WHERE Index BETWEEN 1 AND 5'を実行すると、もっと面白くなります。 –