TRY / CATCH 블록이있는 경우 가능한 원인은 트랜잭션 중단 예외를 포착하고 계속하는 것입니다. CATCH 블록에서는 항상 XACT_STATE()
적절한 중단 및 커밋 할 수없는 (두꺼운) 트랜잭션을 확인 하고 처리 해야 합니다. 호출자가 트랜잭션을 시작하고 calee가 교착 상태 (트랜잭션을 중단 함)에 도달하면 호출 수신자가 트랜잭션이 중단되었으며 '평상시처럼 비즈니스'를 계속해서는 안된다는 것을 호출자에게 어떻게 전달할 것인가? 가능한 유일한 방법은 예외를 다시 발생시켜 호출자가 상황을 처리하도록하는 것입니다. 중단 된 트랜잭션을 조용히 삼키고 호출자가 계속해서 원래 트랜잭션에 있다고 가정하면 신체 상해 만이 보장 할 수 있습니다 (그리고 발생하는 오류는 엔진이 자체 보호를 시도하는 방식입니다).
중첩 트랜잭션 및 예외와 함께 사용할 수있는 패턴을 보여주는 예외 처리 및 중첩 트랜잭션 을 살펴볼 것을 권장합니다 .
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare @trancount int;
set @trancount = @@trancount;
begin try
if @trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
lbexit:
if @trancount = 0
commit;
end try
begin catch
declare @error int, @message varchar(4000), @xstate int;
select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
if @xstate = -1
rollback;
if @xstate = 1 and @trancount = 0
rollback
if @xstate = 1 and @trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
end catch
end
go