2016-10-21 13 views
7

Tôi đang sử dụng TransactionScope trong thời trang sauTransactionAbortedException - bạn có thể chạy lại an toàn không?

using (var scope = new TransactionScope()) 
{ 
    using (var conn = SQLHelpers.GetSQLConnection()) 
    { 
      //commands here 
    } 
    scope.Complete(); 
} 

Đôi khi tôi nhận được một TransactionAbortedException khi gọi scope.Complete() như giao dịch đã được cuộn lại và tôi đã sử dụng các hồ sơ để xác định vấn đề này là một bế tắc.

Giao dịch ngoại lệ (Quy trình ID 59) bị bế tắc trên tài nguyên khóa với quy trình khác và đã được chọn làm nạn nhân bế tắc. Chạy lại giao dịch.

Tôi đã tìm ra nguyên nhân gây ra bế tắc, tuy nhiên nó khiến tôi băn khoăn tại sao lỗi này không bong bóng lên đến TransactionAbortedException để tôi thực sự có thể chạy lại giao dịch chỉ cho trường hợp cụ thể đó. (Các) ngoại lệ bên trong KHÔNG chứa bất kỳ thông tin nào có thể cho biết lỗi thực tế là gì.

Có an toàn để phát hiện TransactionAbortedException làm lý do để chạy lại giao dịch không?

Cho đến nay tôi đã nhìn thấy những ngoại lệ sau bên trong:

1) bế tắc
2) thời gian chờ
3) 'kết nối đã được đóng cửa'
4) .. khác?

chỉ trong một trong các trường hợp này có vẻ thích hợp để chạy lại giao dịch, tuy nhiên bạn có thể khái quát hóa điều này cho tất cả các trường hợp nếu bạn được đảm bảo khôi phục. Câu hỏi có thể được tái khẳng định để hỏi 'không một TransactionAbortedException đảm bảo giao dịch đã được khôi phục'?

+0

Bạn có thấy InnerException của TransactionAbortedException là một thời gian chờ không? –

+0

không có 'InnerException' duy nhất là:' Yêu cầu giao dịch COMMIT không có BEGIN TRANSACTION.' tương ứng và tôi nhận được điều này bởi vì tôi gọi 'scope.Complete' khi giao dịch đã được khôi phục bằng deadlock – wal

+0

Hãy thử điều này nếu (Giao dịch .Current.TransactionInformation.Status == TransactionStatus.Committed) { scope.Complete(); } –

Trả lời

3

Câu hỏi có thể được tái khẳng định để hỏi 'có một TransactionAbortedException đảm bảo giao dịch đã được chuyển quay lại' không?

Các tài liệu cho TransactionAbortedException nói:

ngoại lệ này được ném khi một hành động được thực hiện trên một giao dịch rằng đã được cuộn lại, ví dụ, khi bạn cố gắng để cuộc gọi Commit phương thức trên giao dịch đã hết thời gian chờ. Trường hợp ngoại lệ này cũng bị ném khi thực hiện một nỗ lực để thực hiện giao dịch và hủy giao dịch.

Đây là lỗi có thể khôi phục.

Tôi nghĩ rằng nó là khá rõ ràng từ mô tả này rằng nếu bạn bắt ngoại lệ này, giao dịch của bạn đã không hoàn thành thành công do một số lý do. Sự hiểu biết của tôi về tài liệu là: "Bất kỳ thay đổi nào mà giao dịch đang cố gắng thực hiện đều không được cam kết với cơ sở dữ liệu".

"Đây là lỗi có thể khôi phục", vì vậy nếu bản chất của giao dịch của bạn có ý nghĩa để thử lại, thì bạn nên thử lại sau khi bắt ngoại lệ này.

Bạn có thể muốn giới thiệu một số logic xung quanh thử lại, chẳng hạn như chờ một thời gian trước khi thử lại. Và tăng thời gian chờ đợi này khi số lần thử lại tăng lên. Có giới hạn về tổng số lần thử lại hoặc tổng thời gian thử lại và làm điều gì đó hợp lý/thất bại một cách duyên dáng khi tất cả các lần thử lại không thành công.

Các vấn đề liên quan