문제

ID (Oracle 시퀀스에서 가져온 고유), 카테고리 및 코드 (마지막 두 가지의 제약 조건 없음)의 3 개의 열이있는 테이블을 고려하십시오.

각 카테고리에는 여러 코드가 첨부되어 있지만 코드는 해당 범주 내에서 고유해야합니다. 예시:

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

세 번째는 이미 카테고리 1에 대한 코드 y를 가지고 있기 때문에 괜찮지 않습니다.

이제 삽입하기 전에 실행되는 트리거를 고려하여 삽입 할 값이 정상인지 확인하십시오. 즉, 트리거가 삽입되는 레코드의 경우 범주를 읽은 다음 해당 범주가있는 테이블의 모든 코드를 읽고 이미 삽입 해야하는 레코드의 코드가 이미 존재하는 경우 레코드가 예외를 제기합니다. 삽입되지 않습니다.

내 질문은 트랜잭션 격리 수준이라면 트리거가 테이블에서 "참조"하는 것입니다. READ_COMMITED 그리고 거의 정확히 동시에 두 개의 다른 트랜잭션에서 실행 된 두 개의 인서트가 있지만 트랜잭션은 나중에 커밋됩니다.

예시:

(1) 처음에 테이블은 다음과 같습니다.

ID    CATEGORY   CODE
1     1          X

(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

?!

트리거는 "참조"는 무엇이며 삽입물은 어떻게됩니까?

도움이 되었습니까?

해결책

그러한 검증을 위해 트리거를 사용하지 마십시오. 트리거는 확장되지 않습니다. 또한 알다시피, 그들은 다중 사용자 환경에서 작동하지 않습니다. 이것이 자연이 우리에게 독특한 제약을 준 이유입니다.

alter table your_table
    add constraint yr_tab_uk unique (category, code)
    using index
/
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top