2010-11-19 4 views
0

좋아, 내가 검색을 시도하고 이것에 대한 답변을 찾지 못했습니다 - 롤백 경주 조건을 처리하는 방법 궁금합니다. 예 :경쟁 조건 신용 항목의 업데이트 수정 - 롤백시 어떻게됩니까?

회사에서 구매할 수있는 크레딧 수를 기록하는 테이블 (CompanyAccount)이 있고 (회사 당 데이터베이스 테이블에는 행이 하나뿐입니다) 동일한 사용자의 잠재적 인 사용자가 여러 명있을 수 있습니다 단일 회사 계좌에서 크레딧을 감액 할 수있는 회사, 롤백이 발생하는 경우 오류가 발생하면 어떻게됩니까?

예 :

가정 : 나는 제대로 대신 새로운 신용 잔고가 무엇인지 추측의 새로운 균형을 "신용"을 계산하는 업데이트를 작성했습니다 (즉, 우리는 UPDATE 문을 말하려고하지 않는 어떤 새를

업데이트 DBO : 신용 잔고/값은 여기

업데이트 문을 작성하는 방법의 예입니다 ... 우리는 신용 열에서 무엇이든 받아 UPDATE 문) 내 감소 값을 빼기 말이며, 회사 계좌 SET 크레딧 = 크레딧 - @DecrementAmount WHERE CompanyAccountId = @CompanyAccountId

은 "신용"열이 10,000 크레딧이있는 경우. 사용자 A는 4,000 크레디트를 감소시키고 사용자 B는 1000 크레딧을 감소시킵니다. 어떤 이유로 롤백은 사용자 A의 감소 동안 트리거됩니다 (TRANSACTION 중에 INSERTED 행이있는 테이블이 약 1/12 정도 더 있음). 사용자 A가 경쟁 조건에 도달하고 새 잔액이 6,000 (아직 COMMIT되지 않은 경우) 인 경우 롤백이 적용되기 전에 사용자 B의 감소가 발생하면 어떻게됩니까? 잔액이 6,000에서 5,000으로 증가한 다음 ROLLBACK이 10,000으로 증가합니까?

나는 ROLLBACK이 처리하는 방법에 너무 명확하지 않다. 아마도 나는 지나치게 단순화하고있다. 누군가가 ROLLBACK이 어떻게 작동 할 것인지 또는이 스타일에 대해 걱정할 필요가있는 다른 위험이 있는지 오해하는지 말해 줄 수 있습니까?

입력 해 주셔서 감사합니다. 당신은 아무 문제가 없을 것입니다 준 예에서

답변

3

.

첫 번째 트랜잭션은 배타적 잠금을 가지므로 두 번째 트랜잭션은 커밋되거나 롤백 된 후에야 해당 행을 수정할 수 있습니다. 잠금이 해제 될 때까지 대기 (차단)해야합니다.

문장이 여러 개인 경우 조금 더 복잡해집니다. 당신은 아마도 다른 격리 수준과 "손실 된 업데이트"와 같은 현상을 허용하거나 방지 할 수있는 방법을 읽어야합니다.

+0

(http://msdn.microsoft.com/en-us/library/ms378149.aspx) "두 트랜잭션이 단일 UPDATE 문을 사용하여 행을 업데이트하고 이전에 검색 한 내용을 기반으로하지 않는 경우 값이 손실 된 업데이트는 커밋 된 읽기의 기본 격리 수준에서 발생할 수 없습니다. " – Skyguard

+0

의견/도움에 감사드립니다. – Skyguard

1

롤백은 트랜잭션의 일부이며 롤백 중에는 잠금이 유지됩니다. ACID의 * A * tomic. 모든 잠금이 해제 될 때까지 사용자 B가 시작되지 않습니다.

어떻게됩니까 : 잠금,

  • 사용자 A가 롤백 발표 릴리스 잠금 때까지

    • 사용자 A 잠금 행
    • 사용자 B가 행을 볼 수 없습니다, 변경은 결코 일어나지 않았다.
    • 사용자 B가 행을 봅니다.-1000이 9000이됩니다

    그러나 사용자 B가 이미 잔액을 읽은 경우 업데이트 할 때 일관성이 없습니다. 그것은 당신이 실제로하고있는 순서에 따라 달라집니다. 따라서 isolation levels (그리고 팬텀 및 반복 불가능한 읽기 문제)

    대신 트랜잭션 모드에서 sp_getapplock을 사용할 수 있습니다. 트랜잭션의 세마포어 부분.

  • 관련 문제