Công việc được thực hiện bởi SP2 có thể được cuộn lại và không làm mất công việc được thực hiện bởi SP1. Nhưng để điều này xảy ra, bạn phải viết các thủ tục được lưu trữ của mình bằng một mẫu rất cụ thể, như được mô tả trong Xử lý ngoại lệ và giao dịch lồng nhau :
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
Không phải tất cả các lỗi đều có thể khôi phục được, có một số điều kiện lỗi mà giao dịch không thể khôi phục, ví dụ rõ ràng nhất là deadlock (bạn được thông báo về ngoại lệ deadlock after giao dịch đã quay trở lại). Cả SP1 và [email protected]
phải được viết bằng cách sử dụng mẫu này. Nếu bạn có SP giả mạo hoặc bạn muốn đơn giản tận dụng các quy trình được lưu trữ hiện có gây khó khăn cho việc phát hành ROLLBACK
tuyên bố thì nguyên nhân của bạn bị mất.