2010-06-09 5 views
1

G'daySQL 서버 2005에서 Serializable이 작동하는 방식

제가 serializable에 대한 오해가 있다고 생각합니다. 두 개의 테이블 (데이터, 트랜잭션) serializable 트랜잭션을 삽입 할 정보가 있습니다 (둘 다 또는 둘 다 있지만 limbo 없습니다).

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
BEGIN TRANSACTION 
INSERT INTO dbo.data (ID, data) VALUES (@Id, data) 
INSERT INTO dbo.transactions(ID, info) VALUES (@ID, @info) 
COMMIT TRANSACTION 

읽기 완료 된 격리 수준에서 트랜잭션이없는 항목에 대해 데이터 테이블을 검사하는 조정 쿼리가 있습니다. ID가 복합 (2 열) 키, 그래서 사용할 수없는 사실이다

INSERT INTO reconciles (ReconcileID, DataID) 
SELECT Reconcile = @ReconcileID, ID FROM Data 
WHERE NOT EXISTS (SELECT 1 FROM TRANSACTIONS WHERE data.id = transactions.id) 

주 해당 없음 연산자

나의 이해는 두 번째 쿼리가없이 데이터로 기록 된 모든 값을 제외 것이라고했다 이 삽입이 직렬화시에 발생하고 해당 읽기가 커밋 된 읽기에서 발생했습니다.

그래서 내가 본 것은 Reconcile 쿼리가 격리 수준으로 인해 불가능하다고 생각한이 쿼리와 함께 입력 할 때 데이터 테이블에 있지만 트랜잭션 테이블에있는 데이터 항목을 선택했음을 나타냅니다.

답변

3

모든 트랜잭션 격리 수준은 만을 읽고을 읽습니다. 'read committed'삽입이 없기 때문에 '직렬화 가능'삽입이 없습니다. 쓰기는 직렬화 수준의 영향을받지 않습니다. 두 개의 인서트를 직렬화 레벨 의 모든 레벨이이면, 삽입은 모든 분리 레벨에서 동일하게처럼 동작하므로 no-op입니다.

두 번째 쿼리 인 INSERT ... SELECT ...은 읽기 (SELECT)가 포함되어 있으며, 은 격리 수준의 영향을받으며입니다. SELECT 부분은 현재 격리 수준 (이 경우 읽기 커밋)에 따라 작동합니다.

업데이트 됨 트랜잭션의 쓰기는 커밋 된 후에 만 ​​트랜잭션 외부에서 볼 수 있습니다. 시퀀스가 begin transaction; insert into A; insert into B; commit 인 경우 이상이고 판독 확정 된 격리에서 적어도 인 리더는 B에 삽입되기 전에 A에 삽입되지 않습니다. 조정 쿼리가 부분 트랜잭션을 보는 경우 (즉, A/조정 '쿼리가 잘못된 격리 수준에서 실행하고 더러운 수행한다

  • 읽고 응용 프로그램이 별도로
  • 두 삽입 코드 결함 커밋 않았다 OA 다음 몇 가지 가능한 설명이) B에 삽입 대응 응용 프로그램에서 A에만 삽입하는 결과

가장 가능성있는 설명은 마지막 것입니다.

+0

무슨 일이 있었는지 명확하게 표시하여 제 질문을 업데이트했습니다. Insert는 모든 격리 수준에서 동일하게 작동합니다. 그래서 당신은 그들이 롤백에만 유용하다는 것을 말하고 있습니다. 나는 그것을 작업 단위라고 이해하고 있었으며, 직렬화가 가능하다는 것을 완전히 이해했거나 다시 읽어야한다는 말을 들었습니까? – Spence

관련 문제