2013-06-17 2 views
3

BookAVehicleUnBookAVehicle과 같은 일부 "기본 작업"저장 프로 시저가 있습니다. 그들은 둘 다 거래에 있습니다.SQL Server의 중첩 된 트랜잭션 관련 권장 사항

하지만 지금은 좀 더 복잡한 저장 프로 시저가 필요합니다 : RescheduleBooking. 또한 트랜잭션이어야합니다.

이제 ResceduleBooking에서 BookAVehicle으로 전화를 걸겠습니다.이 경우 내부 트랜잭션을 롤백하지 않으려합니다.

하지만 BookAVehicle을 직접 호출하면 롤백을 유지하려고합니다.

우아하게하는 방법에 대한 제안 사항이 있으십니까?

매개 변수로 저장 프로 시저의 이름을 사용하고 매개 변수 저장 프로 시저에 대한 호출과 트랜잭션 만 포함하는 "래퍼"저장 프로 시저가있는 줄을 따라 생각했습니다.

TransactionWrapper(BookAVehicleWithoutTrans) 

을 내가 다른 트랜잭션에서 호출 할 때 호출 : : 나는 그것을 호출 할 때

그래서 "직접"나는 전화 내부 카운터가

RescheduleBooking -> BookAVehicleWithoutTrans 
+0

을, 마음이 페어링 BEGIN 가정하고 나는 unbook가 실패하는 경우에도 첫 번째 책을 유지합니다 다음과 같은 RescheduleBooking 절차 뭔가를 할 것이다 당신의 책과 UnBook 절차에 거래를 COMMIT 비밀 : 중첩 된 트랜잭션을 지원하는 SQL Server *가 나타납니다. 그러나 실제로는 그렇지 않습니다. 개발자가 눈을 씻기 시작합니다. 중첩 된 트랜잭션 내부로 롤백하면 현재 실행중인 모든 ** 트랜잭션이 롤백됩니다. [Paul Randal의 SQL Server DBA Myth-a-day 게시물] (http://www.sqlskills.com/blogs/paul/a-sql-server-dba-myth-a-day-2630-nested-transactions-are - 진짜 /). –

+0

Nice find marc_s – granadaCoder

+3

[TRY CATCH ROLLBACK 패턴이 포함 된 중첩 저장 프로 시저] 가능한 중복? (http://stackoverflow.com/questions/2073737/nested-stored-procedures-containing-try-catch-rollback-pattern) @marc_s의 링크와 중첩 된 트랜잭션을 일관되게 유지하는 중첩 된 procs와의 중첩 – gbn

답변

1

당신이 트랜잭션을 시작 할 때 증가 된 @@ TRANCOUNT. ROLLBACK TRANSACTION은 모든 BEGIN TRANSACTIONS 설정을 @@ TRANCOUNT로 설정하고 @@ TRANCOUNT를 0으로 롤백합니다. 커밋 트랜잭션을 수행하면 @@ TRANCOUNT 만 감소하며 @@ TRANCOUNT가 1 일 때 전체 커밋을 수행 한 후 0으로 설정합니다.

그것은 약간 더러운 ...

CREATE PROCEDURE RescheduleBooking ... 
AS 
BEGIN 
     BEGIN TRY 
     BEGIN TRANSACTION 
     EXEC BookAVehicle ... 
     COMMIT TRANSACTION 
     END TRY 
     BEGIN CATCH 
     IF @@TRANCOUNT > 0 
     BEGIN 
      ROLLBACK TRANSACTION 
     END 
     RETURN 
     END CATCH; 

    -- If the unbook fails the booking above will still stay. 
     BEGIN TRY 
     BEGIN TRANSACTION 
     EXEC UnBookAVehicle ... 
     COMMIT TRANSACTION 
     END TRY 
     BEGIN CATCH 
     IF @@TRANCOUNT > 0 
     BEGIN 
      ROLLBACK TRANSACTION 
     END 
     RETURN 
     END CATCH; 
END