Als u een TRY/CATCH-blokkering heeft, is de waarschijnlijke oorzaak dat u een uitzondering voor het afbreken van transacties opvangt en doorgaat. In het CATCH-blok moet je altijd de XACT_STATE()
en passende afgebroken en niet-toegezegde (verdoemde) transacties afhandelen. Als uw beller een transactie start en de calee raakt bijvoorbeeld in een impasse (waardoor de transactie is afgebroken), hoe gaat de beller dan aan de beller communiceren dat de transactie is afgebroken en dat deze niet moet doorgaan met 'business as usual'? De enige haalbare manier is om een exception opnieuw te verhogen en de beller te dwingen de situatie af te handelen. Als u stilletjes een afgebroken transactie inslikt en de beller blijft aannemen dat hij nog steeds in de oorspronkelijke transactie zit, kan alleen chaos ervoor zorgen (en de fout die u krijgt is de manier waarop de engine zichzelf probeert te beschermen).
Ik raad je aan om Afhandeling van uitzonderingen en geneste transacties die een patroon toont dat kan worden gebruikt met geneste transacties en uitzonderingen:
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;
-- Do the actual work here
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