如何解決在我的 Azure 角色中突然失去與 SQL Azure 的連接?
我的 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, . . .
即使這樣也可以使用的合理方法:
- 辨識呼叫發生的粗粒度偽事務。
- 將此塊包裝在 try-catch 中。
- 在異常情況下,“回滾”偽事務。
典型工作流程範例:
- 獲取 Azure 隊列消息
- B 從 SQL Azure 查詢數據
- C處理數據,
- D 上傳結果
- E 刪除消息。
在 try-catch 中將 B 到 C 包裝在一起。如果在“無害”的 SQL Azure 呼叫期間發生某些事情,只需在不刪除消息的情況下退出,它會在可見性超時到期後再次彈出。
實際上,這是非常常見的方法:組織成類似事務的塊,將塊包裝成 try-catch,在異常時巧妙地回滾。並且永遠,永遠不要假設某些呼叫不會失敗。所有呼叫不時失敗。