Jika Anda memiliki blok TRY / CATCH maka kemungkinan besar penyebabnya adalah Anda menangkap pengecualian pembatalan transaksi dan melanjutkan. Dalam blok CATCH Anda harus selalu memeriksa XACT_STATE()
dan menangani transaksi yang dibatalkan dan tidak dapat dilakukan (ditakdirkan). Jika penelepon Anda memulai transaksi dan calee menemukan, katakanlah, kebuntuan (yang membatalkan transaksi), bagaimana callee akan mengkomunikasikan kepada penelepon bahwa transaksi telah dibatalkan dan tidak boleh dilanjutkan dengan 'bisnis seperti biasa'? Satu-satunya cara yang layak adalah memunculkan kembali pengecualian, memaksa pemanggil untuk menangani situasi tersebut. Jika Anda diam-diam menelan transaksi yang dibatalkan dan penelepon terus menganggap masih dalam transaksi asli, hanya kekacauan yang dapat memastikan (dan kesalahan yang Anda dapatkan adalah cara mesin mencoba melindungi dirinya sendiri).
Saya sarankan Anda membahas penanganan Exception dan transaksi bersarang yang menunjukkan pola yang dapat digunakan dengan transaksi dan pengecualian bersarang:
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