OracleClient 命令 - 使用和处置命令的最佳实践
根据 OracleClient.OracleCommand 的 MSDN 文档:
Public Sub ReadMyData(ByVal connectionString As String)
Dim queryString As String = "SELECT EmpNo, DeptNo FROM Scott.Emp"
Using connection As New OracleConnection(connectionString)
Dim command As New OracleCommand(queryString, connection)
connection.Open()
Dim reader As OracleDataReader = command.ExecuteReader()
Try
While reader.Read()
Console.WriteLine(reader.GetInt32(0) & ", " _
& reader.GetInt32(1))
End While
Finally
' always call Close when done reading.
reader.Close()
End Try
End Using
End Sub
OracleCommand 未包装在 using 块中。
问: 应该这样吗? OracleCommand 继承自 DbCommand,后者实现了 IDisposable。
我正在查看执行以下操作的代码,并且我们遇到隐式游标未关闭的问题:
Dim cmd As OracleCommand = createCommand("some sql")
ds = GetDataSet(cmd)
cmd.Dispose()
cmd = Nothing
GetDataSet 看起来像:
Dim da As New OracleDataAdapter()
Dim ds As New DataSet()
Using conn As OracleConnection = GetOpenConnection()
cmd.Connection = conn
da.SelectCommand = cmd
da.Fill(ds, 0)
cmd.Connection = Nothing
End Using
da.Dispose()
da = Nothing
Return ds
这会泄漏资源吗?
According to the MSDN documentation for the OracleClient.OracleCommand:
Public Sub ReadMyData(ByVal connectionString As String)
Dim queryString As String = "SELECT EmpNo, DeptNo FROM Scott.Emp"
Using connection As New OracleConnection(connectionString)
Dim command As New OracleCommand(queryString, connection)
connection.Open()
Dim reader As OracleDataReader = command.ExecuteReader()
Try
While reader.Read()
Console.WriteLine(reader.GetInt32(0) & ", " _
& reader.GetInt32(1))
End While
Finally
' always call Close when done reading.
reader.Close()
End Try
End Using
End Sub
The OracleCommand is not wrapped in a Using block.
Question: Should it be? OracleCommand inherits from DbCommand, which implements IDisposable.
I'm looking at code that does the following, and we're having problems with implicit cursors not getting closed:
Dim cmd As OracleCommand = createCommand("some sql")
ds = GetDataSet(cmd)
cmd.Dispose()
cmd = Nothing
GetDataSet looks like:
Dim da As New OracleDataAdapter()
Dim ds As New DataSet()
Using conn As OracleConnection = GetOpenConnection()
cmd.Connection = conn
da.SelectCommand = cmd
da.Fill(ds, 0)
cmd.Connection = Nothing
End Using
da.Dispose()
da = Nothing
Return ds
Is this going to leak resources?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,我认为您应该在代码中显式关闭连接,因为根据提供程序的不同,在调用 Close 方法时需要完成一些额外的工作
First off, I think you should explicitly close your connections in your code, because depending on the provider there is some additional work that gets done when you call the Close method
您如何确定隐式游标已打开并且这是一个问题? 我问的原因是调用“Close”方法实际上并没有关闭连接。 它只是让池知道它不再被使用并且可以重新分配到其他地方。 这样做是出于性能原因,因为实际上物理打开连接的成本很高。 相同的连接将被重复使用很多次,并且即使在调用“关闭”之后也可能保持打开状态,因此如果您使用某些 Oracle 工具来查看连接,它可能会将您引入歧途。
我从未见过任何显式处置命令对象的理由。 它只是参数和其他信息的集合。
如果您像以前一样使用 using 块,则绝对不需要在代码中显式调用“Close”或“Dispose”。 这就是 using 块的全部意义。 它可以防止您忘记调用 Close,因为这正是它为您所做的。
How are you determining that the implicit cursors are open and that that is a problem? The reason I ask is that calling the "Close" method does not actually close the connection. It just lets the pool know that it is no longer being used and can be reallocated somewhere else. This is done for performance reasons because actually physically opening a connection is expensive. The same connection will be reused many times and may well remain open even after calling "Close" so if you are using some Oracle tools to peer into the connections it may be leading you astray.
I have never seen any reason to explicitly dispose of the command object. It is just a collection of parameters and other info.
If you use a using block as you have, there is absolutely no need to call "Close" or "Dispose" explicitly in code. That is the whole point of the using block. It protects you from forgetting to call Close since that is exactly what it does for you.