Dot-Net

如何解決在我的 Azure 角色中突然失去與 SQL Azure 的連接?

  • October 17, 2013

我的 Azure 角色從數據庫中獲取要處理的內容- 它擁有一個實例System.Data.SqlClient.SqlConnection並定期創建一個SqlCommand實例並執行 SQL 查詢。

現在偶爾(通常幾天一次)執行查詢將觸發SqlException異常

服務在處理您的請求時遇到錯誤。請再試一次。錯誤程式碼 40143。目前命令出現嚴重錯誤。結果,如果有的話,應該丟棄。

我已經看過很多次了,現在我的程式碼擷取了它,呼叫Dispose()實例SqlConnection,然後重新打開連接並重試查詢。後者通常會導致另一個SqlException異常

超時已過。在操作完成之前超時時間已過或伺服器沒有響應。

這看起來很像 SQL Azure 伺服器由於某種原因沒有響應或不可用。

目前我的程式碼沒有捕捉到後一個異常,它被傳播到外部RoleEntryPoint.Run()並重新啟動角色。重新啟動通常需要大約十分鐘,一旦完成,問題就會消失一天左右。

我不喜歡我的角色重新啟動 - 這需要一段時間,而且我的服務功能受到阻礙。我想做一些更聰明的事情。

解決這個問題的策略是什麼?我應該多次重試查詢,多少次以及間隔多長時間?我應該做點別的嗎?我什麼時候放棄,讓角色重新開始?

我強烈建議您查看SQL Azure 的瞬態故障處理框架

這將幫助您處理連接和查詢嘗試的重試邏輯,我在生產中使用它並且效果很好。technet 上還有一篇不錯的文章,可能會有一些用處。

$$ EDIT: 17 Oct 2013 $$ 看起來這已被瞬態故障處理應用程序塊的模式和實踐團隊所接受

我們使用 TransientFaultHandling,它不能處理所有奇怪的異常。

例如,昨天彈出了這個:

服務在處理您的請求時遇到錯誤。請再試一次。錯誤程式碼 40143。目前命令出現嚴重錯誤。結果,如果有的話,應該丟棄。, 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, . . .

即使這樣也可以使用的合理方法:

  1. 辨識呼叫發生的粗粒度偽事務。
  2. 將此塊包裝在 try-catch 中。
  3. 在異常情況下,“回滾”偽事務。

典型工作流程範例:

  • 獲取 Azure 隊列消息
  • B 從 SQL Azure 查詢數據
  • C處理數據,
  • D 上傳結果
  • E 刪除消息。

在 try-catch 中將 B 到 C 包裝在一起。如果在“無害”的 SQL Azure 呼叫期間發生某些事情,只需在不刪除消息的情況下退出,它會在可見性超時到期後再次彈出。

實際上,這是非常常見的方法:組織成類似事務的塊,將塊包裝成 try-catch,在異常時巧妙地回滾。並且永遠,永遠不要假設某些呼叫不會失敗。所有呼叫不時失敗。

引用自:https://stackoverflow.com/questions/7006519