ID (一意、Oracle シーケンスから取得)、CATEGORY、および CODE (これらの最後の 2 つは制約なし) の 3 つの列を持つテーブルを考えてみましょう。
各カテゴリには複数のコードが関連付けられていますが、コードはそのカテゴリ内で一意である必要があります。例:
ID CATEGORY CODE
1 1 X
2 1 Y
3 1 Y //wrong
カテゴリ 1 のコード Y が既にあるため、3 番目は OK ではありません。
ここで、挿入の前に実行され、挿入される値に問題がないかどうかを確認するトリガーを考えてみましょう。つまり、挿入されるレコードの場合、トリガーはカテゴリを読み取り、そのカテゴリを持つテーブルからすべてのコードを読み取ります。挿入する必要があるレコードのコードが既に存在する場合は、レコードが挿入されません。
READ_COMMITED
私の質問は、トランザクション分離レベルがで、2 つの異なるトランザクションでほぼ同時に実行される 2 つの挿入があるが、トランザクションが後でコミットされる場合、トリガーはテーブルで何を「見る」のでしょうか?
例:
(1) 最初に、表は次のようになります。
ID CATEGORY CODE
1 1 X
(2) 2 つのトランザクション T1 と T2 があります (READ_COMMITED
両方の分離レベル)。
(3) 両方のトランザクションが、カテゴリ = 1 およびコード = Y を挿入しようとしています。
(4) T1 が挿入を実行し、トリガーが実行されます。表に Y がないので、挿入しても問題ありません。
(5) T2 が挿入を実行し、トリガーが実行されます。テーブルに Y がない (T1 はまだコミットされていない) ため、挿入しても問題ありません。
(6) T1 がコミットし、テーブルは次のようになります。
ID CATEGORY CODE
1 1 X
2 1 Y
(7) T2 がコミットします。そこで何が起こるの?エラーが発生してレコードが挿入されないのですか、それとも次の表が表示されますか?
ID CATEGORY CODE
1 1 X
2 1 Y
3 1 Y //this is wrong
?!
トリガーは何を「認識」し、挿入はどうなりますか?