代码之家  ›  专栏  ›  技术社区  ›  Andrew M

为什么企业库抛出间歇性的“数据连接未能打开”错误?

  •  0
  • Andrew M  · 技术社区  · 16 年前

    我支持一个有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上。

    1 回复  |  直到 16 年前
        1
  •  0
  •   casperOne    16 年前

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

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

    如果您正确地处理了您的连接,那么我将查看该计算机和SQL Server之间的连接,可能您在那里有连接问题。