2014-09-23 37 views
13

完全例外:爲什麼SqlAzureExecutionStrategy不處理:錯誤:19 - 物理連接不可用

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)

爲什麼沒有這個由SqlAzureExecutionStrategy處理? 特別是因爲這發生在VIP互換期間。

編寫自己的DbExecutionStrategy來處理這個問題,還是我錯過了一些東西?

UPDATE 我搬離Azure的雲服務Azure的Web應用程序和次我看到這個錯誤是嚴重的下降量。

+4

我真的希望有人回答這個問題。對我而言,這是Azure中的「預期和正常」,但SqlAzureExecutionStrategy不處理這個特定的錯誤。 – 2014-11-15 13:09:51

+0

報告錯誤。該項目是開源的。承諾每天都在進行。 – usr 2014-11-16 18:05:18

+0

首先它是一個錯誤嗎?這是經常發生的事情,我感覺它是一個設計決定。 – 2014-11-16 18:34:52

回答

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.

那麼這聽起來不像一般的聲明。什麼性能跟蹤器?爲什麼假設開發人員明確打開連接並處理EF?在原始問題中我沒有看到類似的東西(對EF來說這不是常見的做法)。

所以這些問題仍然沒有答案:爲什麼這不是由SqlAzureExecutionStrategy處理?編寫一個自己的DbExecutionStrategy來處理這個問題是一個好主意嗎?

由於我偶爾可以在Azure服務中看到此錯誤,因此我決定對其進行測試。這裏是我的策略:

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; 
     } 
    } 

編輯

好了,所以一段時間,登錄後,我可以告訴大家,在戰略基礎上

if (err.Number == 19) 

錯誤。此錯誤的實際SqlException對象有ErrorCode = -2146232060Number = -1 - 我找不到任何文檔,因此我決定不在他們的基礎上制定策略。現在我想平凡的檢查:

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; 
     } 
    } 

編輯2:

它的工作原理。沒有更多的Physical connection is not usable錯誤,並且沒有RetryLimitExceededException,所以這個錯誤實際上是暫時的(可以通過重試解決),所以我認爲它應該包含在SqlAzureExecutionStrategy中。

+0

非常感謝您試用此功能。我會在一段時間裏碰到你,提醒你:)你的網站是什麼? – 2015-06-17 16:57:07

+0

非常感謝您試用此功能。我想我也要實現這一點,讓我們知道結果。我希望有一天EF(或Azure)團隊的成員可以正式迴應。 – 2015-06-28 18:09:56

+0

ps @rouen,貴賓互換期間,您是否也經常使用此功能? – 2015-06-28 18:11:35

3

如果您已明確打開連接,這是設計決定。微軟稱:

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)

還和我道歉,如果你已經看到了這一點,但茱莉亞數據農場進入詳細瞬態錯誤位相當的。我不確定是否'物理連接不可用'被認爲是短暫的 - 它不包括在System.Data.SqlClient.SqlException的列表中SqlAzureExecutionStrategy的代碼 - 但它可能值得看看:http://thedatafarm.com/data-access/ef6-connection-resiliency-for-sql-azure-when-does-it-actually-do-its-thing/(和她的後續行動,在鏈接文章)。

自2012年以來,我還沒有深入瞭解Azure,但我希望這有助於。

+0

哎呀,只是注意到我寫了「有」,而不是「最後一句」沒有「。這當然改變了這句話的意思!修復它在編輯。 – frasnian 2014-11-23 16:56:02

1

Physical connection is not usable是一大類錯誤,其中一些是暫時的,但有些不是。 SqlAzureExecutionStrategy只重試已知是暫時的特定錯誤。

您應該檢查.Errors集合中包含的所有代碼,以確定是否應該重試該操作。請報告您是否發現SqlAzureExecutionStrategy錯過的特定重複性瞬時錯誤。

也就是說,一旦排除了您的控制下的所有可能原因,一般錯誤-1和-2可以在您的自定義策略中重試:長時間運行的事務,過於複雜的查詢,太多同時打開的連接。

0

我現在的結論是:在 錯誤SqlAzureExecutionStrategy的列表無非就是通過實體框架團隊有把握的猜測以上;並且它通常是過時的,因爲EF不會與SQL Azure同步更新。

我基於這個結論來查看列表的歷史記錄,包括註釋掉的-2錯誤,並將它與其他博客中的其他代碼比較,(現在已過時)瞬態錯誤處理塊和我們親眼看到的不斷變化的實際錯誤。

只要兩個團隊和代碼庫是分開的,這種方法可能不會起作用。如果他們將這個瞬時錯誤列表作爲EF可以查詢和使用的SQL服務器的一個屬性,並使其成爲SQL Azure團隊的工作以使其保持最新和準確,那麼也許這種解決方案將起作用。

與此同時,我的結論是,不會隨機破壞的唯一可行的策略是每例外重試。當然,其中一些可能無用,但唯一可行的方法就是嘗試。

相關問題