我支持一个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!)运行。
答案 0 :(得分:0)
据我所知,当在SqlConnection中创建内部连接对象时会发生这种情况(我相信您是否会使用企业库,我相信)。
我要检查两件事。首先是显而易见的,你是否妥善处理了所有连接?即使您使用连接池,仍然必须在完成使用后对所有连接调用Dispose,以便将它们返回到池中。如果没有,你可能会看到一个饥饿问题。
如果你正确处理你的连接,那么我会查看该机器和SQL Server之间的连接,看起来你可能会遇到连接问题。