32

大容量の .NET アプリケーションでは、クエリを実行しようとすると、次の例外が表示されることがあります。

System.Data.SqlClient.SqlException: サーバーに要求を送信するときに、トランスポート レベルのエラーが発生しました。

私の調査によると、これは「ただ起こる」ものであり、それを防ぐためにできることはあまりありません。これは不適切なクエリの結果として発生するものではなく、通常、複製することはできません。データベースへの TCP 接続が何らかの理由で悪くなると、ビジーな OLTP システムで数日に 1 回発生する可能性があります。

例外メッセージを解析し、新しい接続の使用を含めるために、操作全体を最初から再試行することで、このエラーを検出する必要があります。それはどれもきれいではありません。

誰かが代替ソリューションを持っていますか?

4

11 に答える 11

9

ここで何らかの用途があるかもしれない別のトピックに関する別の質問に回答を投稿しました。その答えには、SQL ではなく SMB 接続が含まれていました。ただし、低レベルの転送エラーが含まれているという点では同じでした。

私たちが発見したことは、高負荷の状況では、サーバーがビジーであるという理由だけで、リモート サーバーが TCP レイヤーで接続をタイムアウトするのはかなり簡単であるということでした。その理由の 1 つは、TCP が Windows でデータを再送信する回数のデフォルトが、私たちの状況に適していなかったことです。

Windows でTCP/IP を調整するためのレジストリ設定を確認してください。特に、 TcpMaxDataRetransmissionsとおそらくTcpMaxConnectRetransmissionsを見たいと思うでしょう。これらのデフォルトはそれぞれ 5 と 2 です。クライアント システムで少し増やして、負荷状況を再現してみてください。

夢中にならないでください!TCP は連続する再送信ごとにタイムアウトを 2 倍にするため、これらを増やしすぎると、接続不良のタイムアウト動作が指数関数的になる可能性があります。TcpMaxDataRetransmissionsを 6 または 7 に上げたことを思い出すと、ほとんどの場合、問題が解決しました。

于 2008-10-16T07:50:23.960 に答える
3

Michael Aspengrenによるこのブログ投稿では、「サーバーにリクエストを送信するときにトランスポートレベルのエラーが発生しました」というエラーメッセージについて説明しています。

于 2010-01-29T07:20:21.690 に答える
2

To answer your original question:

A more elegant way to detect this particular error, without parsing the error message, is to inspect the Number property of the SqlException.

(This actually returns the error number from the first SqlError in the Errors collection, but in your case the transport error should be the only one in the collection.)

于 2008-10-01T05:57:49.720 に答える
1

トランザクションコンポーネントでエンタープライズサービスを使用する

于 2010-07-23T15:24:49.517 に答える
1

私自身の環境でこれが何度も発生するのを見てきました。この場合のクライアント アプリケーションは、多くのマシンにインストールされています。これらのマシンの一部はたまたまラップトップで、人々はアプリケーションを開いたまま切断してから接続し直して使用しようとしていました。これにより、あなたが言及したエラーが発生します。

私の最初のポイントは、ネットワークを調べて、サーバーが DHCP 上になく、このエラーの原因となっている IP アドレスを更新していないことを確認することです。そうでない場合は、イベント ログを調べて他のネットワーク関連を探す必要があります。

残念ながら、上記のネットワーク エラーです。主にできることは、netmon などのツールを使用して接続を監視し、そこから元に戻すことです。

幸運を。

于 2008-10-31T06:30:08.960 に答える
0

I had the same problem. I asked my network geek friends, and all said what people have replied here: Its the connection between the computer and the database server. In my case it was my Internet Service Provider, or there router that was the problem. After a Router update, the problem went away. But do you have any other drop-outs of internet connection from you're computer or server? I had...

于 2008-10-01T06:05:53.583 に答える
0

データベースへのハードウェア接続も確認する必要があります。

おそらく、このスレッドが役立つでしょう: http://channel9.msdn.com/forums/TechOff/234271-Conenction-forcibly-closed-SQL-2005/

于 2008-08-19T18:02:42.170 に答える
0

インストールした新しいソフトウェアについて、当社で機能する修正をここに投稿したかっただけです。クライアント ログ ファイルで 1 日目以降、次のエラーが発生していました: サーバーは要求を処理できませんでした。---> サーバーからの結果の受信時にトランスポート レベルのエラーが発生しました。(プロバイダー: TCP プロバイダー、エラー: 0 - セマフォのタイムアウト期間が過ぎました。) ---> セマフォのタイムアウト期間が過ぎました。

この問題を完全に解決したのは、スイッチにリンク アグリゲート (LAG) をセットアップすることでした。当社の Dell FX1 サーバーには、背面から出ている冗長ファイバー ラインがあります。それらが接続されているスイッチで、これら 2 つのポートに LAG を構成する必要があることを認識していませんでした。詳細はこちらをご覧ください: https://docs.meraki.com/display/MS/Switch+Ports#SwitchPorts-LinkAggregation

于 2015-12-03T16:10:12.597 に答える
0

SQL DB へのサービス リクエストがあったにもかかわらず、私は同じ問題を抱えていました。

これは、サービス エラー ログに記録されていたものです。


System.Data.SqlClient.SqlException: サーバーに要求を送信するときにトランスポート レベルのエラーが発生しました。(プロバイダー: TCP プロバイダー、エラー: 0 - 既存の接続がリモート ホストによって強制的に閉じられました。)


サービスをテストする C# テスト スイートがあります。サービスとDBはどちらも外部サーバー上にあったため、それが問題であると考えました。そのため、サービスとDBをローカルにデプロイしましたが、役に立ちませんでした。問題は続きました。このテスト スイートは、厳密なパフォーマンス テストでさえないので、何が起こっているのかわかりませんでした。毎回同じテストが失敗していましたが、そのテストを無効にすると、別のテストが連続して失敗しました。

インターネットで提案された他の方法も試しましたが、うまくいきませんでした。

  • TcpMaxDataRetransmissionsおよびTcpMaxConnectRetransmissionsのレジストリ値を増やします。
  • [クライアント プロトコル] の下の SQL Server 構成マネージャー内の [共有メモリ] オプションを無効にし、TCP/IP をリストの 1 番目に並べ替えます。
  • これは、多数のクライアント接続試行でスケーラビリティをテストしている場合に発生する可能性があります。この問題を解決するには、regedit.exe ユーティリティを使用して、SynAttackProtect という名前の新しい DWORD 値をレジストリ キー HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ に値データ 00000000 で追加します。

私の最後の手段は、「もう一度試してみてください」という古い年齢を使用することでした。そのため、下位の通信プロトコルで TCP/IP 接続が失われた場合に、そこで断念せずに再試行するように、try-catch ステートメントをネストしました。これは現在私にとってはうまくいっていますが、非常にエレガントなソリューションではありません。

于 2010-07-23T15:19:55.860 に答える
0

DBコマンドの周りに信頼性レイヤーを使用しています(リポジトリインターフェースで抽象化されています)。基本的に、これは予想される例外 (DbException と InvalidOperationException、接続の問題でスローされる) をインターセプトし、それをログに記録し、統計を取得し、すべてを再試行するコードにすぎません。

その信頼性レイヤーが存在することで、サービスはストレステスト (絶え間ないデッドロック、ネットワーク障害など) をうまく乗り切ることができました。生産はそれよりもはるかに敵対的ではありません。

PS:詳細はこちら(傍受 DSL で信頼性を定義する簡単な方法と一緒に)

于 2008-10-01T04:53:59.560 に答える