Đây là mẫu của chúng tôi (đã xóa ghi nhật ký lỗi)
Điều này được thiết kế để xử lý
- Bài viết của Paul Randal " Không có cái gì gọi là giao dịch lồng nhau trong SQL Server "
- Lỗi 266
- Kích hoạt khôi phục lại
Giải thích:
-
tất cả TXN bắt đầu và cam kết / khôi phục phải được ghép nối để
@@TRANCOUNT
vào và ra đều giống nhau -
sự không khớp của
@@TRANCOUNT
gây ra lỗi 266 bởi vì-
BEGIN TRAN
gia số@@TRANCOUNT
-
COMMIT
giảm@@TRANCOUNT
-
ROLLBACK
trả về@@TRANCOUNT
về 0
-
-
Bạn không thể giảm
@@TRANCOUNT
đối với phạm vi hiện tại
Đây là những gì bạn nghĩ là "giao dịch nội bộ" -
SET XACT_ABORT ON
ngăn chặn lỗi 266 do@@TRANCOUNT
không khớp gây ra
Và cũng giải quyết các vấn đề như thế này "Thời gian chờ giao dịch của máy chủ SQL" trên dba.se -
Điều này cho phép các TXN phía máy khách (như LINQ) Một quy trình được lưu trữ duy nhất có thể là một phần của giao dịch phân tán hoặc XA, hoặc đơn giản là một quy trình được khởi tạo trong mã máy khách (giả sử .net TransactionScope)
Cách sử dụng:
- Mỗi proc được lưu trữ phải tuân theo cùng một mẫu
Tóm tắt
- Vì vậy, đừng tạo nhiều TXN hơn mức bạn cần
Mã
CREATE PROCEDURE [Name]
AS
SET XACT_ABORT, NOCOUNT ON
DECLARE @starttrancount int
BEGIN TRY
SELECT @starttrancount = @@TRANCOUNT
IF @starttrancount = 0
BEGIN TRANSACTION
[...Perform work, call nested procedures...]
IF @starttrancount = 0
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @starttrancount = 0
ROLLBACK TRANSACTION;
THROW;
--before SQL Server 2012 use
--RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
END CATCH
GO
Ghi chú:
-
Kiểm tra khôi phục thực sự là thừa vì
SET XACT_ABORT ON
. Tuy nhiên, nó làm cho tôi cảm thấy tốt hơn, trông kỳ lạ mà không có và cho phép những trường hợp bạn không muốn nó diễn ra -
Remus Rusanu có trình bao tương tự sử dụng điểm lưu. Tôi thích gọi DB nguyên tử hơn và không sử dụng các bản cập nhật từng phần như bài viết của họ