2009-08-31 13 views
1

ID(ユニーク、Oracleシーケンスから取得)、CATEGORYおよびCODE(これらの最後の2つの制約はありません)の3つの列を持つ表を考えてみます。現在のトランザクション分離レベルでトリガーが実行されていますか?

各カテゴリには複数のコードが添付されていますが、コードはそのカテゴリ内で一意である必要があります。例:

ID CATEGORY CODE 
1  1   X 
2  1   Y 
3  1   Y  //wrong 

三番目は、我々はすでに、カテゴリ1

のコードYを持っているので、今すぐに挿入する値がOKかどうかを確認するために、挿入をチェックする前に実行するトリガを考慮OKではありません。つまり、挿入されているレコードでは、トリガがカテゴリを読み取り、そのカテゴリを持つテーブルからすべてのコードを読み込み、挿入する必要があるレコードのコードが既に存在する場合は例外を発生させ、レコード挿入されていません。

私の質問は、トランザクション分離レベルがREAD_COMMITEDあり、そこに二つの異なるトランザクションで実行する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 

:私はエラーを取得し、レコードが挿入されていないか、私は次の表を得るのですか?!

トリガーは「参照」とは何か、挿入物はどうなりますか?

答えて

7

このような検証にトリガーを使用しないでください。トリガーは拡大縮小されません。また、気づいたとおり、マルチユーザー環境では動作しません。これが自然が私たちにユニークな制約を与えた理由です。

alter table your_table 
    add constraint yr_tab_uk unique (category, code) 
    using index 
/
+3

1:可能な限り、トリガーの代わりに制約を使用。この場合、トリガは、MUTATIONエラー(ORA-4091)が発生するため、ベース表に問い合せることができません。 –

+0

@APCちょっと、これと似たような質問がありますが、特定のカテゴリでは1つのYしか許されませんが、Xの複数の出現を許しています。この場合、 'unique'はうまく適合しません。 –

+0

@JerryChin - あなたは新鮮な質問をする必要がある十分に異なるシナリオのように聞こえます。あなたが持っているすべての状態をカバーするサンプルデータを必ず含めてください。 – APC

関連する問題