Saya lebih suka merekomendasikan pola seperti yang dari Exception Handling dan Nested Transactions :
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
Pola ini memeriksa XACT_STATE()
dalam blok penahan untuk menjaga dari transaksi yang tidak dapat dilakukan :
Transaksi yang Tidak Terjanjikan dan XACT_STATE
Jika kesalahan yang dihasilkan dalam blok TRY menyebabkan keadaan transaksi saat ini menjadi tidak valid, transaksi tersebut diklasifikasikan sebagai transaksi yang tidak dapat dipastikan. Kesalahan yang biasanya mengakhiri transaksi di luar blok TRY menyebabkan transaksi memasuki kondisi yang tidak dapat dikomit ketika kesalahan terjadi di dalam blok TRY. Transaksi yang tidak dapat dilakukan hanya dapat melakukan operasi baca atau TRANSAKSI ROLLBACK. Transaksi tidak dapat menjalankan pernyataan Transact-SQL apa pun yang akan menghasilkan operasi penulisan atau TRANSAKSI KOMIT. Fungsi XACT_STATE mengembalikan nilai -1 jika transaksi telah diklasifikasikan sebagai transaksi yang tidak dapat dilakukan. Ketika batch selesai, Mesin Database memutar kembali setiap transaksi aktif yang tidak dapat dilakukan. Jika tidak ada pesan kesalahan yang dikirim saat transaksi memasuki kondisi yang tidak dapat diterima, ketika batch selesai, pesan kesalahan akan dikirim ke aplikasi klien. Ini menunjukkan bahwa transaksi yang tidak dapat dideteksi terdeteksi dan dibatalkan.
Kode Anda memeriksa @@TRANCOUNT
di tempat-tempat di mana itu tidak dapat 0, ia menggunakan campuran pesan PRINT informasi dan set hasil SELECT untuk berkomunikasi keberhasilan, itu tidak menangani kesalahan yang dapat dipulihkan. Idealnya pengecualian harus menyebar ke klien, dalam hal ini untuk pekerjaan Agen (mis. Tangkapan Anda harus naik kembali).