Почему Enterprise Library выдает периодически возникающие ошибки «Не удалось открыть соединение для передачи данных»?

Я поддерживаю 3-летнюю службу Windows (C # .Net 1.1), которая использует Enterprise Library для управления своими подключениями к SQL-серверу. Служба отслеживает входящие сообщения и выполняет различные задачи в зависимости от сообщения, большинство из которых включает обновление базы данных. Насколько я знаю, сервис является однопоточным и читает сообщения из очереди по одному.

Несколько раз за последние несколько дней мы видели, как он «ломался» случайно (последний раз около полуночи прошлой ночью). В это время некоторые, но не все обновления БД дают сбой (возможно, около 20%), мы видим много предупреждений в журнале событий и ошибки в наших файловых журналах (воспроизведены ниже). Перезапуск службы заставляет все работать снова отлично.

Я думаю, возможно, это как-то связано с пулами соединений в Enterprise Library? Возможно ли, что корпоративная библиотека пытается поддерживать пул большего количества соединений, чем позволяет сервер БД? Но я не могу понять, почему это так, и почему это не будет более изящным.

Есть ли способ получить немного больше информации из журналов моей корпоративной библиотеки относительно реальной причины этих сбоев?

Предупреждения в журнале событий выглядят примерно так: (слегка отредактировано)

    Источник: Служба данных библиотеки предприятия
    Описание: Соединение с данными не удалось открыть: сервер = имя_сервера; база данных = имя_базы_интегрированной безопасности = true;

Одновременно в файле журнала ошибок мы видим исключения Null Reference из библиотеки Enterprise, при вызове из нашего сервиса, что-то вроде этого: (опять же, слегка отредактировано)

    Возникла исключительная ситуация типа System.NullReferenceException.
    -------------------------------------------------- ---------------------------
    17.02.2009 15:00:52
    Тип: System.NullReferenceException, mscorlib, версия = 1.0.5000.0, культура = нейтральная, PublicKeyToken = b77a5c561934e089
    Сообщение: ссылка на объект не установлена ​​на экземпляр объекта.
    Источник: System.Data
    Справочная ссылка: 
    TargetSite: System.Data.SqlClient.SqlInternalConnection CreateConnection ()
    Трассировка стека: в System.Data.SqlClient.ConnectionPool.GetConnection (Boolean & isInTransaction)
       в System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection (параметры SqlConnectionString, Boolean & isInTransaction)
       в System.Data.SqlClient.SqlConnection.Open ()
       в Microsoft.Practices.EnterpriseLibrary.Data.Database.OpenConnection ()
       в Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery (команда DBCommandWrapper)
       в OurCode.SomeFunction (сообщение MessageType) в C: \ someClass.cs: строка 45
       в OurCode.SomeOtherFunction (сообщение XmlReader)

    Дополнительная информация:

    MachineName: MachineName TimeStamp: 17/02/2009 15:00:52
    Полное имя: Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, версия = 1.1.0.0, культура = нейтральная, PublicKeyToken = a8dcbcfec587cc95
    AppDomainName: OurCode.service.exe
    ThreadIdentity: 
    WindowsIdentity: OurDomain \ SomeAccount

Ранее (в предыдущей «сломанной» фазе) мы видели исключения, подобные этой: (еще раз, слегка отредактировано, чтобы быть застенчивым!). Это то, что заставило меня подозревать, что у пула соединений возникают проблемы. Я думаю, что именно здесь наш код регистрирует свою (не ошибочную) активность в БД, но код корпоративной библиотеки не может снова установить соединение с БД (всегда в сочетании с ошибками «Не удалось открыть соединение данных», упомянутым ранее).

    Не удалось выполнить прием, поскольку: System.NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта.
       в System.Data.SqlClient.ConnectionPool.GetConnection (Boolean & isInTransaction)
       в System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection (параметры SqlConnectionString, Boolean & isInTransaction)
       в System.Data.SqlClient.SqlConnection.Open ()
       в Microsoft.Practices.EnterpriseLibrary.Data.Database.OpenConnection ()
       в Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery (команда DBCommandWrapper)
       at OurCode.Diagnostics.CustomDatabaseSink.ExecuteStoredProcedure (LogEntry logEntry)
       в OurCode.Diagnostics.CustomDatabaseSink.SendMessageCore (LogEntry logEntry).

Любая помощь, особенно указатели для получения дополнительной информации из нашего журнала высоко ценится.

Другая справочная информация: служба Windows написана на C # .Net 1.1 и работает на Windows Server 2003, под учетной записью домена (которая имеет все необходимые разрешения для необходимых БД). Сервер БД - это SQL 2005, работающий в режиме совместимости 2000 (ура!) В Windows Server 2008.

17.02.2009 17:26:50
1 ОТВЕТ
РЕШЕНИЕ

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

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

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

0
17.02.2009 17:30:18
Просто примечание: вызов .Close () для соединения неявно вызывает .Dispose (), поэтому, если он использует .Close (), он в порядке.
HardCode 17.02.2009 17:32:24
@HardCode: Да, но нигде нет указаний на это. Кроме того, это деталь реализации, поэтому Dispose должен быть предпочтительнее, чем Close.
casperOne 17.02.2009 17:35:34
Хорошо, я углублюсь в код и проверю это, но я подумал, что при использовании библиотеки Enterprise она открывает и закрывает соединения для вас. То есть, наш код отправляет команду SQL функциям корпоративной библиотеки, но не открывает соединение. Корпоративная библиотека делает все это за нас.
Andrew M 17.02.2009 17:48:14
@ Эндрю М: Да, но вы все равно можете подключиться и использовать его самостоятельно, если хотите. Я не вижу ваш код, поэтому я не могу сказать, делаете ли вы это или нет.
casperOne 17.02.2009 17:58:35
Хорошо, я углублюсь в код и посмотрю, что происходит. Я выложу соответствующие куски, если смогу. TBC. Спасибо
Andrew M 17.02.2009 18:05:21