Я поддерживаю 3-летнюю службу Windows (C # .Net 1.1), которая использует Enterprise Library для управления своими подключениями к SQL-серверу. Служба отслеживает входящие сообщения и выполняет различные задачи в зависимости от сообщения, большинство из которых включает обновление базы данных. Насколько я знаю, служба однопоточная и читает сообщения из очереди по одному.
Пару раз за последние несколько дней мы видели, как он "случайно" ломался (последний раз около полуночи прошлой ночью). В это время некоторые, но не все обновления БД дают сбой (возможно, около 20%), мы видим много предупреждений в журнале событий и ошибки в наших файловых журналах (воспроизведены ниже). Перезапуск службы заставляет все работать снова отлично.
Я думаю, возможно, это как-то связано с пулом соединений в Enterprise Library? Возможно ли, что библиотека Enterprise пытается поддерживать пул большего количества соединений, чем позволяет сервер БД? Но я не могу понять, почему это так, и почему это не будет более изящным.
Есть ли способ получить немного больше информации из журналов моей корпоративной библиотеки относительно реальной причины этих сбоев?
Предупреждения в журнале событий выглядят примерно так: (слегка отредактировано)
Source: Enterprise Library Data Service
Description: Data connection failed to open: server=ServerName;database=DatabaseNameintegrated security=true;
Одновременно в файле журнала ошибок мы видим исключения Null Reference из библиотеки Enterprise, при вызове из нашего сервиса, что-то вроде этого: (опять же, слегка отредактировано)
An exception of type 'System.NullReferenceException' occurred and was caught.
-----------------------------------------------------------------------------
02/17/2009 15:00:52
Type : System.NullReferenceException, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Object reference not set to an instance of an object.
Source : System.Data
Help link :
TargetSite : System.Data.SqlClient.SqlInternalConnection CreateConnection()
Stack Trace : at System.Data.SqlClient.ConnectionPool.GetConnection(Boolean& isInTransaction)
at System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection(SqlConnectionString options, Boolean& isInTransaction)
at System.Data.SqlClient.SqlConnection.Open()
at Microsoft.Practices.EnterpriseLibrary.Data.Database.OpenConnection()
at Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery(DBCommandWrapper command)
at OurCode.SomeFunction(MessageType message) in C:\someClass.cs:line 45
at OurCode.SomeOtherFunction(XmlReader message)
Additional Info:
MachineName : MachineName TimeStamp : 17/02/2009 15:00:52
FullName : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=1.1.0.0, Culture=neutral, PublicKeyToken=a8dcbcfec587cc95
AppDomainName : OurCode.service.exe
ThreadIdentity :
WindowsIdentity : OurDomain\SomeAccount
Ранее (в предыдущей «сломанной» фазе) мы видели исключения вроде этого: (еще раз, слегка отредактированный, чтобы быть скромным!). Это то, что заставило меня подозревать, что у пула соединений возникают проблемы. Я думаю, что именно здесь наш код регистрирует свою (не ошибочную) активность в БД, но код корпоративной библиотеки не может снова установить соединение с БД (всегда в сочетании с ошибками «Не удалось открыть соединение данных», упомянутым ранее.
Sink failed because: System.NullReferenceException: Object reference not set to an instance of an object.
at System.Data.SqlClient.ConnectionPool.GetConnection(Boolean& isInTransaction)
at System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection(SqlConnectionString options, Boolean& isInTransaction)
at System.Data.SqlClient.SqlConnection.Open()
at Microsoft.Practices.EnterpriseLibrary.Data.Database.OpenConnection()
at Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery(DBCommandWrapper command)
at OurCode.Diagnostics.CustomDatabaseSink.ExecuteStoredProcedure(LogEntry logEntry)
at OurCode.Diagnostics.CustomDatabaseSink.SendMessageCore(LogEntry logEntry).
Любая помощь, особенно указатели для получения дополнительной информации из нашего журнала очень ценится.
Другая справочная информация:
Служба Windows написана на C # .Net 1.1 и работает на Windows Server 2003, под учетной записью домена (которая имеет все необходимые права доступа к нужным БД).
Сервер БД - это SQL 2005, работающий в режиме совместимости 2000 (ура!) В Windows Server 2008.