c# - 使用 IDbConnection/IDbTransaction 安全吗?

标签 c# vb.net transactions database-connection using-statement

虽然我的假设听起来很主观,但经过一些研究后,我发现开发人员喜欢使用虚拟 Try/Catch 而不是使用 Using statement 的情况并不少见。用于 IDbConnection/IDbTransaction 处理(关闭/提交/回滚)。

这甚至适用于一些经验最丰富的开发人员和一些新开发人员。我有意不引用 StackOverflow 上的任何问题或论坛链接作为示例,这样人们就不会被冒犯。来自 what I found , Using语句是safe to use (没有双关语意)。

有什么问题吗?考虑以下代码:

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 上的 Dispose?这种方法是否会在不久的将来停用,或者在现代编程模式/最佳实践中是否被认为不够清楚?单声道/移动应用程序开发工具缺乏对 Using 关键字的调试支持?

我正在寻找任何类型的答案来支持或否认这一点。最好是带有原始文档引号的那个,比如 Do not use Using with IDbTransaction when ...。也可以链接到博客或个人经历。

最佳答案

我完全同意你的观点;这应该是 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。

关于c# - 使用 IDbConnection/IDbTransaction 安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16903289/

相关文章:

c# - RSACryptoServiceProvider 从 C# 到 VB 的转换

spring - REST 幂等实现 - 如何在已处理请求时回滚?

java - 多战耳发现预绑定(bind) JDBC 连接

apache-kafka - Kafka 是否支持 XA 事务?

c# - linq 如何选择具有包含一个或多个值数组(或列表)的子集合的父项

c# - 在 ASP.NET Core 上检测与 SSE 的断开连接

c# - 将一个二维数组转换为两个一维数组

c# - 如何检测光线转换的相机?

javascript - 登录网站失败

vb.net - 如何在运行时更改列表框中的选定项文本?