MERGE
すべてのセッションで主キー列に異なる値 (以下のスニペットで *** として示されています) を使用しているときに同時s をid
実行する場合、2 つのターミナル セッションで手動で実行するとすべて問題ありません。
MERGE
INTO x
USING (SELECT *** as id FROM DUAL) MERGE_SRC
ON (x.id = MERGE_SRC.id)
WHEN MATCHED THEN UPDATE SET val = val + 1 WHERE id = ***
WHEN NOT MATCHED THEN INSERT VALUES (***, 99);
COMMIT;
ただし、3 つ以上のスレッドでマルチスレッド負荷テストを実行すると、比較的すぐにORA-08177 with locked table
. 何故ですか?(そして、トランザクションがオーバーラップするときに常に発生するとは限らないという点で、なぜ非決定論的なのでしょうか?)
テーブルは次を使用して作成されました
create table x (id int primary key, val int);
SQL Serverところで、同じ実験を実行して、同等のMERGEステートメントで例外をスローすることはありません。これは、同じ行で同時に作業している場合にも当てはまります。
おそらくMERGEがアトミックではなく、シリアライズ可能なモードが楽観的に実行されるため、レースが十分な競合でのみ表示される可能性がありますか? それでも、同じ行を同時に処理していなくても、なぜそれが起こるのでしょうか?
ところで、利用可能な最も厳格なロックを使用してこれを修正しようとする私の試みは失敗しました。したがって、このアトミックを作成する方法についてのアイデアは非常に高く評価されています。分離レベルを緩和すると例外が取り除かれるように見えますが、同じ行に 2 つの更新がある場合に矛盾が発生するリスクがあります (それ以外の場合、最初にシリアル化可能モードでボークするのはなぜですか)。