我支持一个有3年历史的Windows服务(C.NET 1.1),它使用企业库来管理与SQL Server的连接。服务监视传入的消息,并根据消息执行各种任务,其中大多数任务涉及更新数据库。据我所知,服务是单线程的,每次从队列中读取一条消息。
在过去的几天里,有几次我们看到它随机“中断”(上次是在昨晚午夜左右)。在这段时间内,有些(但不是所有)对数据库的更新都失败了(大约20%),我们在事件日志中看到了大量警告,在文件日志中也看到了错误(在下面复制)。重新启动服务会使一切恢复正常。
我在想也许这和企业库中的连接池有关?企业库是否可能试图维护的连接池超过了数据库服务器允许的数量?但我不明白为什么会这样,为什么它不会失败得更优雅一点。
有没有一种方法可以让我从企业库日志中获得更多信息,从而了解这些失败的真正原因?
事件日志中的警告看起来类似:(稍微编辑过)
Source: Enterprise Library Data Service
Description: Data connection failed to open: server=ServerName;database=DatabaseNameintegrated security=true;
同时,在错误日志文件中,当从我们的服务调用时,我们会看到来自企业库的空引用异常,如下所示:(再次,稍微编辑一下)
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框中的域帐户下运行(该帐户对所需的DBS具有所有权限)。
数据库服务器是SQL 2005,在2000兼容模式下运行(yay legacy!),在Windows Server 2008上。