为什么Enterprise Library会抛出间歇性的“数据连接无法打开”错误?

时间:2009-02-17 17:26:50

标签: c# .net sql-server enterprise-library

我支持一个3岁的Windows服务(C#.Net 1.1),它使用Enterprise Library来管理它与SQL服务器的连接。该服务监视传入的消息,并根据消息执行各种任务,其中大部分涉及更新数据库。据我所知,该服务是单线程的,并且一次一个地从队列中读取消息。

在过去的几天里,我们已经看到它几次随意“破裂”(最后一次是在昨晚午夜时分)。在这些时候,数据库的某些但不是所有更新都会失败(大约20%),我们在事件日志中看到很多警告,并且我们的文件日志中出现错误(在下面再现)。重新启动服务可以使一切恢复正常。

我想也许这与企业库中的连接池有关?是否有可能企业库试图维护一个比DB服务器允许的更多连接池?但我不明白为什么会这样,以及为什么它不会更优雅地失败。

有没有办法可以从我的企业库日志中获取更多信息,了解这些失败的真正原因?

事件日志中的警告类似于:(略有编辑)

    Source: Enterprise Library Data Service
    Description: Data connection failed to open: server=ServerName;database=DatabaseNameintegrated security=true;

同时,在错误日志文件中,当从我们的服务调用时,我们会看到来自Enterprise库的Null引用异常,如下所示:(再次,稍加编辑)

    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

早些时候(在之前的“破碎”阶段),我们看到了像这样的例外情况:(再一次,稍微编辑就是腼腆!)。这就是让我怀疑连接池存在问题的原因。我认为这是我们的代码将其(非错误)活动记录到数据库的地方,但企业库代码无法再次连接到数据库(总是与前面提到的“数据连接无法打开”错误相关联。 / p>

    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,在Windows Server 2008上以2000兼容模式(Yay legacy!)运行。

1 个答案:

答案 0 :(得分:0)

据我所知,当在SqlConnection中创建内部连接对象时会发生这种情况(我相信您是否会使用企业库,我相信)。

我要检查两件事。首先是显而易见的,你是否妥善处理了所有连接?即使您使用连接池,仍然必须在完成使用后对所有连接调用Dispose,以便将它们返回到池中。如果没有,你可能会看到一个饥饿问题。

如果你正确处理你的连接,那么我会查看该机器和SQL Server之间的连接,看起来你可能会遇到连接问题。