2009-08-31 6 views
1

ID (고유, Oracle 시퀀스에서 가져옴), CATEGORY 및 CODE (이 마지막 두 개의 제약 조건 없음)의 세 열이있는 테이블을 생각해보십시오.트리거가 현재 트랜잭션 격리 수준으로 실행됩니까?

각 카테고리에는 연결된 코드가 여러 개 있지만 코드는 해당 카테고리 내에서 고유해야합니다. 예 :

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

우리는 이미 이제 삽입 할 값이 OK하면 삽입 및 여부를 확인하기 전에 실행되는 트리거를 고려 범주 1.

에 대한 코드 Y이 있기 때문에 세 번째는 확인되지 않습니다 . 즉, 삽입되는 레코드의 경우 트리거가 범주를 읽고 해당 범주가있는 모든 코드를 테이블에서 읽은 다음 삽입해야하는 레코드의 코드가 이미 있으면 예외가 발생하여 레코드가 삽입되지 않았습니다.

제 질문은 트랜잭션 격리 수준이 READ_COMMITED이고 두 개의 다른 트랜잭션에서 거의 정확하게 동시에 실행되지만 트랜잭션이 나중에 커밋되는 경우 테이블에서 트리거가 "보게"됩니까?

예 :

(1) 우선, 표는 다음과 같다 :

ID CATEGORY CODE 
1  1   X 

2 개의 트랜잭션이 T1 및 T2 (모두 격리 레벨 READ_COMMITED)이있다;

(3) 두 트랜잭션 모두 category = 1 및 code = 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이 질문과 비슷한 질문이 있는데, 유일한 차이점은 특정 카테고리에 대해 하나의 Y 만 허용된다는 것입니다. X의 여러 모양을 허용하는 반면,이 경우에는 '고유'가 적합하지 않습니다. –

+0

@JerryChin - 신선한 질문을하는 데 필요한 시나리오가 아주 다른 것 같습니다. 보유하고있는 모든 주를 다루는 샘플 데이터를 포함 시키십시오. – APC