14

私のAzureロールは、データベースから処理するものを取得します。インスタンスを保持し、System.Data.SqlClient.SqlConnection定期的にSqlCommandインスタンスを作成して、SQLクエリを実行します。

たまに(通常は数日に1回)クエリを実行するとSqlException例外がトリガーされます

サービスでリクエストの処理中にエラーが発生しました。もう一度やり直してください。エラーコード40143。現在のコマンドで重大なエラーが発生しました。結果がある場合は、破棄する必要があります。

これはすでに何度も見てきましたが、コードがそれをキャッチしDispose()SqlConnectionインスタンスを呼び出してから、接続を再度開いてクエリを再試行します。後者は通常、別のSqlException例外が発生します

タイムアウトが期限切れになりました。操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません。

これは、SQLAzureサーバーが何らかの理由で応答しないか利用できないように見えます。

現在、私のコードは後者の例外をキャッチしていません。それは外部RoleEntryPoint.Run()に伝播され、役割が再開されます。通常、再起動には約10分かかります。再起動が完了すると、問題は1日ほど解消されます。

役割を再開するのは好きではありません。しばらく時間がかかり、サービス機能が妨げられます。もっと賢いことをしたいのですが。

この問題に対処するための戦略は何でしょうか?クエリを数回、何回、どのような間隔で再試行する必要がありますか?私は何か他のことをすべきですか?いつあきらめて、役割を再開させますか?

4

2 に答える 2

14

SQLAzureの一時的な障害処理フレームワークを確認することを強くお勧めします

これは、接続とクエリの両方の試行の再試行ロジックを処理するのに役立ちます。私はこれを本番環境で使用しており、うまく機能します。technetには、役に立つかもしれない素敵な記事もあります。

[編集:2013年10月17日]

これは、一時的な障害処理アプリケーションブロックのパターンおよび実践チームによって取り上げられたようです。

于 2011-08-10T07:14:38.910 に答える
2

TransientFaultHandling を使用していますが、奇妙な例外のすべてを処理するわけではありません。

たとえば、これは昨日ポップアップしました。

リクエストの処理中にサービスでエラーが発生しました。もう一度やり直してください。エラー コード 40143。現在のコマンドで重大なエラーが発生しました。結果がある場合は、破棄する必要があります。、System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() の System.Data.SqlClient.SqlConnection.OnError(SqlException 例外、Boolean breakConnection) でのスタックトレース (RunBehavior runBehavior、SqlCommand cmdHandler、. . .

これでも機能する合理的なアプローチ:

  1. 呼び出しが発生する大まかな擬似トランザクションを特定します。
  2. このブロックを try-catch でラップします。
  3. 例外では、疑似トランザクションを「ロールバック」します。

一般的なワークフローの例:

  • Get Azure キュー メッセージ
  • B SQL Azure からのクエリ データ
  • Cプロセスデータ、
  • Dアップロード結果
  • E メッセージを削除します。

B から C までを try-catch でラップします。「無害な」SQL Azure 呼び出し中に何かが発生した場合、メッセージを削除せずに単純に救済し、可視性タイムアウトの期限が切れた後に再びポップアップします。

実際、これは非常に一般的なアプローチです。トランザクションのようなブロックに編成し、ブロックを try-catch にラップし、例外が発生したらきちんとロールバックします。また、一部の呼び出しが失敗しないと想定しないでください。すべての呼び出しが時々失敗します。

于 2012-12-07T18:49:42.767 に答える