虽然我的假设听起来似乎是主观的,但经过一些研究后,我发现,开发人员喜欢使用虚拟Try/Catch而不是使用使用语句进行IDbConnection/IDbTransaction处理(关闭/提交/回滚)并不少见。
即使是一些经验最丰富的开发人员和一些新开发人员也是如此。我有意不引用StackOverflow或论坛链接上的任何问题作为例子,这样人们就不会被冒犯。在我发现的中,使用语句是安全使用 (没有双关意)。
有什么问题吗?考虑以下代码:
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假设{CREATE_CONNECTION}是根据所有可能的最佳实践编写的、根据数据库供应商创建连接的Sub的位置持有者,并且不需要更多的改进。
是否有理由不能将上述代码重写为:
Using cn As IDbConnection = {CREATE_CONNECTION}
cn.Open()
Using tran As IDbTransaction = cn.BeginTransaction
'run some queries here
tran.Commit()
End Using
End Using很明显,第2版对它所做的事情更加直观。但也许我错过了一些重要的东西?比如特定于供应商的数据访问库的实现,而不是在内部调用Transaction.Commit和/或Connection.Close?这种方法是在不久的将来退役,还是在现代编程模式/最佳实践中不够明确?Mono/mobile应用程序开发工具缺乏对Using关键字的调试支持?
我正在寻找任何一种答案来支持或否认这一点。最好是带有原始文档引号的那个,类似于Do not use Using with IDbTransaction when ...。链接到博客或个人体验也是可以的。
发布于 2013-06-03 18:35:23
我完全支持您的连接;这应该是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;
}
}在复杂程度上介于两者之间。至少,这并不是在胡闹null-checks。
发布于 2013-06-03 18:36:10
您看到的是开发人员根据文档编写代码(“好事”)。基类DbTransaction (用于大多数数据提供程序的事务实现)在其文件中明确声明。
Dispose应该回滚事务。但是,Dispose的行为是特定于提供程序的,不应该取代调用回滚。
https://stackoverflow.com/questions/16903289
复制相似问题