1

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

?!

トリガーは何を「認識」し、挿入はどうなりますか?

4

1 に答える 1

7

このような検証にはトリガーを使用しないでください。トリガーはスケーリングしません。また、お気づきのとおり、マルチユーザー環境では機能しません。これが、自然が私たちに独自の制約を与えた理由です。

alter table your_table
    add constraint yr_tab_uk unique (category, code)
    using index
/
于 2009-08-31T09:31:58.733 に答える