Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Các thủ tục được lưu trữ lồng nhau có chứa mẫu TRY CATCH ROLLBACK?

Đâ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ý

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

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 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ọ



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách hoạt động của hàm STR () trong SQL Server (T-SQL)

  2. Cần trợ giúp trong truy vấn động với Mệnh đề IN

  3. Làm cách nào để lấy danh sách ID từ bảng SQL dưới dạng chuỗi giá trị được phân tách bằng dấu phẩy?

  4. Chỉ mục máy chủ SQL thích hợp để chỉ chèn lược đồ

  5. Các ký tự đại diện trong Bộ sưu tập SSIS {không bao gồm} tên xlsx