【问题标题】:DataAdapter is not closing connection by itselfDataAdapter 不会自行关闭连接
【发布时间】:2014-12-05 04:52:08
【问题描述】:

我们知道,如果连接尚未打开,DataAdapter 会打开和关闭连接。但是使用我的代码它打开但不关闭..我正在使用 MySql.Data.MySqlClient.MySqlDataAdapter,不确定我做错了什么。下面是我的代码

Public Function GetDT(ByVal SqlQuery As String, ByVal ConString As String) As DataTable
    Dim da As New MySql.Data.MySqlClient.MySqlDataAdapter(SqlQuery, ConString)
    Dim ds As New DataSet
    da.Fill(ds)
    GetDT = ds.Tables(0)
    da.Dispose()
    ds.Dispose()
    da = Nothing
    ds = Nothing
End Function

我正在使用这个连接字符串:"server=localhost;port=3306;user=someuser;pwd=somepassword;database=mydatabasename;Allow Zero Datetime=True;"

在调试代码时,我在 DataAdapter.fill 执行它时立即启动了一个连接线程,但是由于线程保持在 SLEEP 状态,因此连接没有关闭。请检查下图。

谁能帮我解决这个问题?

谢谢

【问题讨论】:

  • 不确定这是否是解决办法,但您应该在处理 da 之前处理掉 ds。否则,您将在关闭其父连接后关闭 ds
  • 我试过了,但如果我在 da 之前处理 ds 没有任何改变

标签: mysql database-connection dataadapter


【解决方案1】:

这是正常行为,因为 ADO.NET 默认使用 SQL Server 连接池。来自 MSDN:

http://msdn.microsoft.com/en-US/library/8xx3tyca(v=vs.110).aspx

连接到数据库服务器通常包括几个 耗时的步骤。物理通道,例如套接字或命名 管道必须建立,与服务器的初始握手必须 发生时,必须解析连接字符串信息, 连接必须由服务器验证,必须运行检查 加入当前事务,依此类推。

实际上,大多数应用程序只使用一种或几种不同的 连接的配置。这意味着在申请期间 执行时,将重复打开许多相同的连接,并且 关闭。为了最小化打开连接的成本,ADO.NET 使用 称为连接池的优化技术。

连接池减少了新连接的次数 必须打开。池子保持物理的所有权 联系。它通过保持一组活动来管理连接 每个给定连接配置的连接。每当用户 在连接上调用 Open,池化程序会寻找可用的 池中的连接。如果一个池连接可用,它 将其返回给调用者,而不是打开新连接。 当 应用程序在连接上调用 Close,pooler 将其返回给 池化的活动连接集,而不是关闭它。一旦 连接被返回到池中,它已准备好在 下一次公开通话。

....

连接池程序在连接池中删除一个连接后 闲置了大约 4-8 分钟,...

DataAdapter 中“使用”或“处置”的效果是一样的。 “使用”确保 dispose 被执行,即使发生异常。与使用 try / finally 语句并将“dispose”放在 finally 部分相同。

【讨论】:

  • 我没有完全明白,但听起来 DA 并没有自行关闭连接。我说的对吗?
  • 当您调用 dispose 或使用语句结束时,它不会关闭,而是将连接返回到池中。如果出于某种原因不需要连接池(但对性能有好处),您可以通过 ConnectionString 禁用它,然后您的连接将关闭而不是返回池。您可以添加 ;pooling=false
【解决方案2】:

连接仅在您使用Using 指令时自行关闭,Using 语句可用于任何实现IDisposable 接口的对象。

在 DataAdapter 的 Dispose() 方法中,连接在释放对象之前关闭。 正确使用它会是这样的。

Public Function GetDT(ByVal SqlQuery As String, ByVal ConString As String) As DataTable
    Using da As New MySql.Data.MySqlClient.MySqlDataAdapter(SqlQuery, ConString)
        Dim ds As New DataSet
        da.Fill(ds)
        GetDT = ds.Tables(0)
        da.Dispose()   //because you are now using a 'Using' statement, this method is not necessary anymore.
        ds.Dispose()
        da = Nothing
        ds = Nothing
    End Using
End Function

【讨论】:

  • 我试过你的代码,它没有关闭数据库连接
  • 您是否尝试过执行 da.Connection.Close() 或 da.Connection.Dispose()?我不太确定,但我认为 DataAdapter 具有访问连接对象的属性
  • 没有 da.Connection 属性
  • Yes 属性存在,但 da.SelectCommand.Connection.Close() 无法关闭连接。
  • 正如上面 IAG 所说,我们需要在连接字符串中添加 pooling=false
猜你喜欢
  • 2019-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
相关资源
最近更新 更多