Почему Enterprise Library выдает периодически возникающие ошибки «Не удалось открыть подключение к данным»? - PullRequest
0 голосов
/ 17 февраля 2009

Я поддерживаю 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.

1 Ответ

0 голосов
/ 17 февраля 2009

Из того, что я могу сказать, это происходит, когда объект внутреннего соединения создается в SqlConnection (я полагаю, вы получите это с помощью корпоративной библиотеки или нет).

Есть две вещи, которые я бы проверил. Во-первых, очевидно, правильно ли вы удаляете все свои соединения? Даже если вы используете пул соединений, вы все равно должны вызывать Dispose для всех ваших соединений, когда вы их используете, чтобы они возвращались в пул. Если нет, то вы можете посмотреть на проблему с голодом.

Если вы удаляете свои соединения должным образом, то я бы посмотрел на соединение между этой машиной и SQL Server, может показаться, что у вас там проблема с соединением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...