Enterprise Library を使用して SQL サーバーへの接続を管理する 3 年前の Windows サービス (C# .Net 1.1) をサポートしています。このサービスは受信メッセージを監視し、メッセージに応じてさまざまなタスクを実行します。そのほとんどはデータベースの更新を伴います。私の知る限り、このサービスはシングル スレッドであり、一度に 1 つずつキューからメッセージを読み取ります。
ここ数日で、ランダムに「壊れる」のを数回見ました(前回は昨夜の真夜中頃)。この間、DB へのすべての更新ではなく一部の更新が失敗し (約 20% 程度)、イベント ログに多数の警告が表示され、ファイル ログにエラーが記録されます (以下に再現)。サービスを再起動すると、すべてが再び完全に機能します。
おそらく、Enterprise Library の接続プールと関係があるのではないでしょうか? Enterprise ライブラリが、DB サーバーが許可するよりも多くの接続のプールを維持しようとしている可能性はありますか? しかし、なぜそれが失敗するのか、なぜもう少しうまく失敗しないのかわかりません。
これらの失敗の本当の理由について、エンタープライズ ライブラリのログ記録からもう少し情報を得る方法はありますか?
イベントログの警告は次のようになります: (少し編集)
出典: エンタープライズ ライブラリ データ サービス 説明: データ接続を開くことができませんでした: server=ServerName;database=DatabaseNameintegrated security=true;
同時に、サービスから呼び出されたときに、エンタープライズ ライブラリからの Null 参照例外がエラー ログ ファイルに表示されます。
タイプ 'System.NullReferenceException' の例外が発生し、キャッチされました。 -------------------------------------------------- --------------------------- 2009/02/17 15:00:52 タイプ: System.NullReferenceException、mscorlib、Version=1.0.5000.0、Culture=neutral、PublicKeyToken=b77a5c561934e089 メッセージ : オブジェクト参照がオブジェクトのインスタンスに設定されていません。 ソース: System.Data ヘルプリンク : TargetSite : System.Data.SqlClient.SqlInternalConnection CreateConnection() スタック トレース: System.Data.SqlClient.ConnectionPool.GetConnection(Boolean& isInTransaction) で System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection (SqlConnectionString オプション、ブール値 & isInTransaction) で System.Data.SqlClient.SqlConnection.Open() で Microsoft.Practices.EnterpriseLibrary.Data.Database.OpenConnection() で Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery (DBCommandWrapper コマンド) で C:\someClass.cs:line 45 の OurCode.SomeFunction(MessageType message) で OurCode.SomeOtherFunction (XmlReader メッセージ) で 追加情報: MachineName: MachineName タイムスタンプ: 17/02/2009 15:00:52 FullName : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling、バージョン = 1.1.0.0、カルチャ = ニュートラル、PublicKeyToken = a8dcbcfec587cc95 AppDomainName : OurCode.service.exe スレッド ID : WindowsIdentity : OurDomain\SomeAccount
以前 (以前の「壊れた」段階で)、次のような例外が見られました: (もう一度、恥ずかしがり屋に少し編集しました!) これが、接続プーリングに問題があると思わせた理由です。これは、コードが(エラーではない)アクティビティをDBに記録する場所だと思いますが、エンタープライズライブラリコードはDBへの接続を再度取得できません(常に前述の「データ接続を開けませんでした」というエラーと相まって.
シンクが失敗した理由: System.NullReferenceException: オブジェクト参照がオブジェクトのインスタンスに設定されていません。 System.Data.SqlClient.ConnectionPool.GetConnection (ブール値 & isInTransaction) で System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection (SqlConnectionString オプション、ブール値 & isInTransaction) で System.Data.SqlClient.SqlConnection.Open() で Microsoft.Practices.EnterpriseLibrary.Data.Database.OpenConnection() で Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery (DBCommandWrapper コマンド) で OurCode.Diagnostics.CustomDatabaseSink.ExecuteStoredProcedure (LogEntry logEntry) で OurCode.Diagnostics.CustomDatabaseSink.SendMessageCore (LogEntry logEntry) で。
ヘルプ、特にログからより多くの情報を取得するためのポインターは大歓迎です。
その他の背景情報: Windows サービスは C# .Net 1.1 で記述されており、Windows Server 2003 ボックス上で、ドメイン アカウント (必要な DB に対するすべての適切なアクセス許可を持っています) の下で実行されます。DB サーバーは SQL 2005 であり、Windows Server 2008 で 2000 互換モード (Yay legacy!) で実行されています。