2014-09-23 15 views
13

Full ngoại lệ:Tại sao SqlAzureExecutionStrategy không xử lý: lỗi: 19 - kết nối vật lý không phải là có thể sử dụng

System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)

Tại sao không được này xử lý bởi các SqlAzureExecutionStrategy? Đặc biệt vì điều này xảy ra trong quá trình hoán đổi VIP.

Ý tưởng hay là viết DbExecutionStrategy riêng để xử lý vấn đề này hoặc tôi có thiếu gì đó không?

CẬP NHẬT tôi chuyển từ Azure dịch vụ đám mây-Azure Web Apps và số lần tôi nhìn thấy lỗi này được giảm nghiêm trọng.

+4

Tôi thực sự hy vọng ai đó sẽ trả lời câu hỏi này. Nó là không thể tin được với tôi rằng điều này là "mong đợi và bình thường" trong Azure, nhưng SqlAzureExecutionStrategy không xử lý lỗi cụ thể này. –

+0

Báo cáo lỗi. Dự án là nguồn mở. Cam kết đang đến qua mỗi ngày. – usr

+0

Đây có phải là lỗi ở nơi đầu tiên không? Đó là điều xảy ra thường xuyên đến nỗi tôi có cảm giác đó là một quyết định thiết kế. –

Trả lời

13

From the profiler trace we observe that the same connection is used for each query database query. This is by design and as discussed early, i.e. when a connection is explicitly opened by the developer it tells EF not to open/reopen a connection for each command.

Điều này chắc chắn không giống như tuyên bố chung. Những gì profiler dấu vết? Tại sao giả sử kết nối được mở bởi nhà phát triển và được xử lý cho EF? Tôi không thấy bất cứ điều gì như thế này trong câu hỏi ban đầu (và nó không phải là thực tế phổ biến với EF).

Vì vậy, các câu hỏi vẫn chưa được trả lời: Tại sao điều này không được xử lý bởi SqlAzureExecutionStrategy? Nó là một ý tưởng tốt để viết một DbExecutionStrategy riêng mà xử lý này?

Vì tôi có thể thấy lỗi này trong dịch vụ Azure của mình theo thời gian, tôi đã quyết định thử nghiệm nó. Đây là chiến lược của tôi:

public class ExtendedSqlAzureExecutionStrategy : SqlAzureExecutionStrategy 
    { 
     public ExtendedSqlAzureExecutionStrategy(int maxRetryCount, TimeSpan maxDelay) : base(maxRetryCount, maxDelay) 
     { } 

     protected override bool ShouldRetryOn(Exception exception) 
     { 
      return base.ShouldRetryOn(exception) || IsPhysicalConnectionNotUsableSqlException(exception); 
     } 

     private bool IsPhysicalConnectionNotUsableSqlException(Exception ex) 
     { 
      var sqlException = ex as SqlException; 
      if (sqlException != null) 
      { 
       // Enumerate through all errors found in the exception. 
       foreach (SqlError err in sqlException.Errors) 
       { 
        if (err.Number == 19) 
        { 
         return true; 
        }      
       } 
      } 

      return false; 
     } 
    } 

EDIT

Ok, vì vậy sau một thời gian khai thác gỗ và tôi có thể nói rằng chiến lược dựa trên

if (err.Number == 19) 

sai. Đối tượng SqlException thực tế cho lỗi này có ErrorCode = -2146232060Number = -1 - Tôi không thể tìm thấy bất kỳ tài liệu nào cho chúng, vì vậy tôi quyết định không dựa trên chiến lược đó. Để bây giờ tôi đang cố gắng kiểm tra tầm thường:

public class ExtendedSqlAzureExecutionStrategy : SqlAzureExecutionStrategy 
    { 
     public ExtendedSqlAzureExecutionStrategy(int maxRetryCount, TimeSpan maxDelay) : base(maxRetryCount, maxDelay) 
     { } 

     protected override bool ShouldRetryOn(Exception exception) 
     { 
      return base.ShouldRetryOn(exception) || IsPhysicalConnectionNotUsableSqlException(exception); 
     } 

     private bool IsPhysicalConnectionNotUsableSqlException(Exception ex) 
     { 
      var sqlException = ex as SqlException; 
      if (sqlException != null) 
      { 
       return sqlException.Message.Contains("Physical connection is not usable"); 
      } 

      return false; 
     } 
    } 

EDIT 2:

Nó hoạt động. Không còn Physical connection is not usable lỗi nào nữa và không có RetryLimitExceededException, vì vậy lỗi này thực tế thoáng qua (có thể giải quyết bằng cách thử lại), vì vậy tôi nghĩ rằng nó nên được bao gồm trong SqlAzureExecutionStrategy.

+0

Cảm ơn bạn rất nhiều vì đã dùng thử. Tôi sẽ làm phiền bạn trong một thời gian để nhắc nhở bạn :) trang web của bạn là gì? –

+0

Cảm ơn rất nhiều vì đã dùng thử. Tôi nghĩ rằng tôi cũng sẽ thực hiện điều này và cho biết kết quả. Tôi hy vọng một ngày nào đó, một người trong nhóm EF (hoặc Azure) có thể trả lời chính thức điều này. –

+0

ps @rouen, bạn cũng có điều này đặc biệt thường xuyên trong quá trình hoán đổi VIP không? –

3

Nếu bạn đã mở kết nối rõ ràng, đây là quyết định thiết kế. Microsoft cho biết:

From the profiler trace we observe that the same connection is used for each query database query. This is by design and as discussed early, i.e. when a connection is explicitly opened by the developer it tells EF not to open/reopen a connection for each command. The series of Audit Login/Logout events to retrieve the customer entity or address entity are not submitted as we saw in Case #1 and #2. This means we cannot implement a retry policy for each individual query like I showed earlier. Since the EntityConnection has been assigned to the ObjectContext, EF takes the position that you really truly want to use one connection for all of your queries within the scope of that context. Retrying a query on an invalid or closed connection can never work, a System.Data.EntityCommandExecutionException will be thrown with an inner SqlException contains the message for the error. (see http://blogs.msdn.com/b/appfabriccat/archive/2010/12/11/sql-azure-and-entity-framework-connection-fault-handling.aspx)

Ngoài ra, và tôi xin lỗi nếu bạn đã thấy điều này, nhưng Julia tại trang trại dữ liệu đi vào chi tiết một chút cho các lỗi tạm thời. Tôi không chắc liệu 'Kết nối vật lý có thể sử dụng được' được coi là tạm thời không được bao gồm trong danh sách cho System.Data.SqlClient.SqlException trong mã cho SqlAzureExecutionStrategy - nhưng có thể đáng xem: http://thedatafarm.com/data-access/ef6-connection-resiliency-for-sql-azure-when-does-it-actually-do-its-thing/ (và theo dõi của cô ấy, được tham chiếu trong bài viết được liên kết).

Tôi chưa nhìn sâu vào Azure kể từ khoảng năm 2012, nhưng tôi hy vọng điều này sẽ hữu ích.

+0

Rất tiếc, chỉ cần nhận thấy rằng tôi đã viết "có" thay vì "chưa" trong câu cuối cùng đó. Điều đó chắc chắn đã thay đổi ý nghĩa của câu đó! Sửa lỗi chỉnh sửa. – frasnian

1

Physical connection is not usable là một loại lỗi lớn, một số lỗi tạm thời, nhưng một số thì không. SqlAzureExecutionStrategy chỉ thử lại các lỗi cụ thể được biết là tạm thời.

Bạn nên kiểm tra tất cả các mã có trong bộ sưu tập .Errors để xác định xem hành động có nên được thử lại hay không. Vui lòng báo cáo nếu bạn tìm thấy các lỗi tạm thời định kỳ cụ thể mà SqlAzureExecutionStrategy bỏ qua.

Điều đó nói rằng, lỗi chung -1 và -2 có thể được thử lại trong chiến lược tùy chỉnh của bạn sau khi bạn loại trừ tất cả các nguyên nhân có thể có trong tầm kiểm soát của bạn: giao dịch chạy dài, truy vấn quá phức tạp, quá nhiều kết nối đồng thời mở.

0

kết luận hiện tại của tôi là thế này: danh sách các sai sót trong SqlAzureExecutionStrategy là gì khác hơn là một đoán giáo dục bởi nhóm Entity Framework; và nó thường lỗi thời vì EF không được cập nhật đồng bộ với SQL Azure.

Tôi căn cứ vào kết quả này của danh sách, bao gồm lỗi đã nhận xét -2 và so sánh nó với các danh sách khác trong các đoạn mã khác xung quanh blog, khối xử lý lỗi tạm thời (lỗi thời) các lỗi thực tế luôn thay đổi mà chúng tôi đang gặp phải.

Miễn là hai nhóm và mã số riêng biệt, phương pháp này có thể sẽ không hoạt động. Nếu họ đưa ra danh sách các lỗi tạm thời là thuộc tính của máy chủ SQL mà EF có thể truy vấn và sử dụng, và biến nó thành công việc của nhóm SQL Azure để cập nhật và chính xác, thì giải pháp này có thể hoạt động.

Trong khi chờ đợi, kết luận của tôi là chiến lược khả thi duy nhất không ngẫu nhiên phá vỡ, là thử lại mọi ngoại lệ. Chắc chắn, một số người trong số họ có lẽ là vô ích để thử lại, nhưng cách chắc chắn duy nhất là để thử.

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