0

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

在过去的几天里,有几次我们看到它随机“中断”(最后一次是在昨晚午夜左右)。在这些时间里,对数据库的一些(但不是全部)更新失败(大约 20% 可能),我们在事件日志中看到很多警告,在我们的文件日志中看到错误(在下面重现)。重新启动服务使一切再次完美运行。

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

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

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

    来源:企业图书馆数据服务
    说明:数据连接打开失败:server=ServerName;database=DatabaseNameintegrated security=true;

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

    发生并捕获了“System.NullReferenceException”类型的异常。
    -------------------------------------------------- --------------------------
    2009 年 2 月 17 日 15:00:52
    类型:System.NullReferenceException,mscorlib,版本=1.0.5000.0,文化=中性,PublicKeyToken=b77a5c561934e089
    消息:对象引用未设置为对象的实例。
    来源:System.Data
    帮助链接:
    目标站点:System.Data.SqlClient.SqlInternalConnection CreateConnection()
    堆栈跟踪:在 System.Data.SqlClient.ConnectionPool.GetConnection(Boolean& isInTransaction)
       在 System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection(SqlConnectionString 选项,布尔值& isInTransaction)
       在 System.Data.SqlClient.SqlConnection.Open()
       在 Microsoft.Practices.EnterpriseLibrary.Data.Database.OpenConnection()
       在 Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery(DBCommandWrapper 命令)
       在 C:\someClass.cs:line 45 中的 OurCode.SomeFunction(MessageType message)
       在 OurCode.SomeOtherFunction(XmlReader 消息)

    附加信息:

    机器名称:机器名称时间戳:17/02/2009 15:00:52
    全名:Microsoft.Practices.EnterpriseLibrary.ExceptionHandling,版本=1.1.0.0,文化=中性,PublicKeyToken=a8dcbcfec587cc95
    应用域名:OurCode.service.exe
    线程身份:
    WindowsIdentity:OurDomain\SomeAccount

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

    接收器失败,因为:System.NullReferenceException:对象引用未设置为对象的实例。
       在 System.Data.SqlClient.ConnectionPool.GetConnection(Boolean& isInTransaction)
       在 System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection(SqlConnectionString 选项,布尔值& isInTransaction)
       在 System.Data.SqlClient.SqlConnection.Open()
       在 Microsoft.Practices.EnterpriseLibrary.Data.Database.OpenConnection()
       在 Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery(DBCommandWrapper 命令)
       在 OurCode.Diagnostics.CustomDatabaseSink.ExecuteStoredProcedure(LogEntry logEntry)
       在 OurCode.Diagnostics.CustomDatabaseSink.SendMessageCore(LogEntry logEntry)。

非常感谢任何帮助,尤其是从我们的日志中获取更多信息的指针。

其他背景信息:windows 服务是用 C# .Net 1.1 编写的,在 Windows Server 2003 机器上运行,在域帐户下(对所需的 DB 具有所有正确权限)。数据库服务器是 SQL 2005,在 Windows Server 2008 上以 2000 兼容模式(Yay legacy!)运行。

4

1 回答 1

0

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

我要检查两件事。首先很明显,您是否正确处理了所有连接?即使您正在使用连接池,您仍然必须在使用完所有连接后调用 Dispose,以便将它们返回到池中。如果没有,您可能正在查看饥饿问题。

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

于 2009-02-17T17:30:18.417 回答