vb.net 用于 IDbConnection/IDbTransaction 安全使用吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16903289/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using for IDbConnection/IDbTransaction safe to use?
提问by Neolisk
While my assumption may seem to sound subjective, after some research, I found that it's not uncommon to find developers who favour a dummy Try/Catchinstead of using the Using statementfor IDbConnection/IDbTransactionprocessing (Close/Commit/Rollback).
虽然我的假设听起来似乎很主观,但经过一些研究后,我发现开发人员喜欢使用哑元Try/Catch而不是使用Using 语句进行IDbConnection/IDbTransaction处理(关闭/提交/回滚)的情况并不少见。
This holds true for even some of the most seasoned developers and some new ones. I am intentionally not going to reference any of the question on StackOverflow or forum links as an example, so people don't get offended. From what I found, Usingstatement is safe to use(no pun intended).
即使是一些最有经验的开发人员和一些新的开发人员也是如此。我故意不参考 StackOverflow 上的任何问题或论坛链接作为例子,所以人们不会被冒犯。根据我的发现,Using语句可以安全使用(没有双关语)。
Is there anything wrong with it? Consider the following code:
有什么问题吗?考虑以下代码:
Public Sub Commit()
Dim cn As IDbConnection = {CREATE_CONNECTION}
Dim tran As IDbTransaction = Nothing
cn.Open()
Try
tran = cn.BeginTransaction
'run some queries here
tran.Commit()
Catch ex As Exception
If Not tran Is Nothing Then tran.Rollback()
Throw
Finally
cn.Close()
End Try
End Function
Assume {CREATE_CONNECTION}is place holder for a Subthat creates a connection, depending on the database vendor, written according to all possible best practices and does not need more improvement.
Assume{CREATE_CONNECTION}是用于Sub创建连接的占位符,具体取决于数据库供应商,根据所有可能的最佳实践编写,不需要更多改进。
Is there a reason why the above code cannot be rewritten as such:
上面的代码不能改写成这样有什么原因吗:
Using cn As IDbConnection = {CREATE_CONNECTION}
cn.Open()
Using tran As IDbTransaction = cn.BeginTransaction
'run some queries here
tran.Commit()
End Using
End Using
?
?
Clearly, version #2 is more intuitive to what it's doing. But perhaps I am missing something important here? Things like vendor-specific implementations of data access libraries, that do not call Transaction.Commitand/or Connection.Closeon Disposeinternally? Is this approach being decommissioned in the near future, or not regarded as clear enoughin modern programming pattern/best practices? Mono/mobile apps dev tools lacking debug support for Usingkeyword?
显然,第 2 版对其所做的事情更直观。但也许我在这里遗漏了一些重要的东西?诸如数据访问库的特定于供应商的实现之类的东西,不会在内部调用Transaction.Commit和/或调用?这种方法是在不久的将来退役,还是在现代编程模式/最佳实践中不够清晰?缺乏对关键字的调试支持的单声道/移动应用程序开发工具?Connection.CloseDisposeUsing
I am looking for any kind of answer to support or deny the point. Preferably the one with quotes to original documentation, something like Do not use Using with IDbTransaction when .... Links to blogs or personal experience are okay too.
我正在寻找任何类型的答案来支持或否认这一点。最好是带有原始文档引号的文件,例如Do not use Using with IDbTransaction when .... 指向博客或个人经验的链接也可以。
回答by Marc Gravell
I'm entirely with you on the connection; that should be using, and there is no need for the explicit Close(). The transaction is a little bit trickier; the code shown is certainly overkill at the moment, but it is not entirely defined that Dispose()should do a rollback. Actually, that iswhat tends to happen in every implementation I've looked at, but it is slightly vexing that even DbTransaction(which most providers use) doesn't actually do this. Contrast to TransactionScopewhere it is explicitly defined that a Dispose()without a commit counts as a rollback. Because of that, I tendto use (excuse the C#):
我完全支持你;那应该是using,而且不需要显式的Close()。交易有点棘手;目前显示的代码肯定是矫枉过正,但并没有完全定义Dispose()应该进行回滚。实际上,这就是我看过的每个实现中都会发生的情况,但有点令人烦恼的是,即使DbTransaction(大多数提供者使用的)实际上并没有这样做。与TransactionScope明确定义Dispose()没有提交算作回滚的地方相反。因此,我倾向于使用(请原谅 C#):
using(var conn = GetOpenConnection())
using(var tran = conn.BeginTransaction()) {
try {
// TODO: do work
tran.Commit();
} catch {
tran.Rollback();
throw;
}
}
which is somewhere between the two in terms of complexity. It isn't messing around with null-checks, at least.
就复杂性而言,它介于两者之间。null至少,它不会与-checks 混为一谈。
回答by Michael Gunter
What you're seeing is developers coding according to the documentation (a "Good Thing"). The base class DbTransaction (used for most data providers' transaction implementations) states clearly in its documentation:
您所看到的是开发人员根据文档进行编码(“好事”)。基类 DbTransaction(用于大多数数据提供者的事务实现)在其文档中明确说明:
Dispose should rollback the transaction. However, the behavior of Dispose is provider specific, and should not replace calling Rollback.
Dispose 应该回滚事务。但是,Dispose 的行为是特定于提供程序的,不应取代调用 Rollback。

