2011-08-10 31 views
14

Vai trò Azure của tôi grabs stuff to process from a database - nó giữ một phiên bản System.Data.SqlClient.SqlConnection và định kỳ tạo một cá thể SqlCommand và thực thi truy vấn SQL.Làm cách nào để giải quyết đột ngột mất kết nối với SQL Azure trong vai trò Azure của tôi?

Bây giờ một lần trong một thời gian (thường là một lần trong vài ngày) chạy một truy vấn sẽ kích hoạt một SqlException ngoại lệ

Dịch vụ này đã gặp sự cố thực hiện yêu cầu của bạn. Vui lòng thử lại. Mã lỗi 40143. Đã xảy ra lỗi nghiêm trọng trên lệnh hiện tại. Các kết quả, nếu có, cần được loại bỏ.

Mà tôi đã nhìn thấy nhiều lần và bây giờ mã của tôi bắt nó, gọi Dispose() trên SqlConnection dụ và sau đó mở lại kết nối và thử lại truy vấn. Thông tin sau thường dẫn đến một ngoại lệ SqlException khác

Hết hạn. Khoảng thời gian chờ trôi qua trước khi hoàn thành thao tác hoặc máy chủ không phản hồi.

Có vẻ như máy chủ SQL Azure không phản hồi hoặc không khả dụng vì bất kỳ lý do gì.

Hiện tại mã của tôi không bắt ngoại lệ thứ hai, nó được lan truyền bên ngoài RoleEntryPoint.Run() và vai trò được khởi động lại. Khởi động lại thường mất khoảng mười phút và sau khi hoàn thành vấn đề đã biến mất trong một ngày hoặc lâu hơn.

Tôi không thích vai trò của mình đang khởi động lại - phải mất một lúc và chức năng dịch vụ của tôi bị cản trở. Tôi muốn làm điều gì đó thông minh hơn.

Chiến lược để giải quyết vấn đề này là gì? Tôi có nên thử lại truy vấn nhiều lần và bao nhiêu lần và với khoảng thời gian nào không? Tôi có nên làm gì khác không? Khi nào tôi bỏ cuộc và để vai trò vừa mới khởi động lại?

Trả lời

14

Tôi rất muốn giới thiệu bạn có một cái nhìn tại Transient Fault Handling Framework for SQL Azure

Điều này sẽ giúp bạn xử lý thử lại logic cho cả hai kết nối và truy vấn cố gắng, tôi đang sử dụng này trong sản xuất và nó hoạt động tuyệt vời. Ngoài ra còn có một bài viết tốt đẹp on technet mà có thể được sử dụng một số.

[EDIT: 17 tháng 10 năm 2013]

Nó trông như thế này đã được chọn của các đội mẫu và thông lệ tại The Transient Fault Handling Application Block

+0

Cũng có sẵn qua nuget. – dunnry

+0

Cảm ơn dunnry Tôi đã không phát hiện ra điều đó. Tôi đổ lỗi cho Wade vì không giữ cho chúng tôi đúng cách được cập nhật;) –

+5

Trang web Xử lý lỗi tạm thời có lỗi không ổn định: bị lỗi. – Rory

2

Chúng tôi sử dụng TransientFaultHandling và nó không xử lý tất cả các trường hợp ngoại lệ kỳ lạ.

Ví dụ: ứng dụng này xuất hiện ngày hôm qua:

Dịch vụ đã gặp lỗi khi xử lý yêu cầu của bạn. Vui lòng thử lại. Mã lỗi 40143. Đã xảy ra lỗi nghiêm trọng trên lệnh hiện tại. Các kết quả, nếu có, cần được loại bỏ. , stacktrace tại System.Data.SqlClient.SqlConnection.OnError (ngoại lệ SqlException, Boolean breakConnection) tại System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() tại System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior, SqlCommand cmdHandler, ...

Cách tiếp cận hợp lý rằng sẽ làm việc ngay cả với điều này:

  1. Xác định một giả giao dịch hạt thô mà các cuộc gọi xảy ra.
  2. Quấn khối này trong trò chơi thử.
  3. ngoại lệ, 'quay lại' giao dịch giả.

Ví dụ về một công việc điển hình:

  • Một lấy Azure nhắn đợi
  • truy vấn dữ liệu B từ SQL Azure
  • trình C dữ liệu, kết quả
  • D upload
  • E xóa thông điệp.

Quấn B qua C với nhau trong một lần thử. Nếu một cái gì đó xảy ra trong cuộc gọi SQL Azure 'vô hại', đơn giản là giải cứu mà không xóa thư, nó sẽ chỉ xuất hiện trở lại sau khi hết thời gian hiển thị.

Thực ra, đây là cách tiếp cận rất phổ biến: tổ chức thành các khối giống như giao dịch, chặn khối thành thử-catch, gọn gàng quay lại ngoại lệ. Và không bao giờ, không bao giờ giả định rằng một số cuộc gọi không thất bại. Tất cả các cuộc gọi không thành công theo thời gian.

+1

Tôi đồng ý với cách tiếp cận của bạn, nhưng câu trả lời của David Steele cũng chính xác. Trong thực tế cả hai câu trả lời đối phó với các cấp độ khác nhau. Bạn sử dụng Khung xử lý lỗi tạm thời để xử lý các lỗi tạm thời; nếu tình hình vẫn tồn tại, bạn hủy bỏ hoạt động hiện tại và thử lại sau (hoặc bỏ đi). –

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