.net - SqlTransaction 是否需要调用 Dispose?

标签 .net transactions dispose sqltransaction

我需要在 SqlTransaction 的 finally block 中调用 dispose 吗?假装开发人员没有在任何地方使用 USING,然后尝试/捕获。

SqlTransaction sqlTrans = con.BeginTransaction();

try
{
     //Do Work
sqlTrans.Commit()
}
catch (Exception ex)
        {

           sqlTrans.Rollback();
        }

 finally
        {
            sqlTrans.Dispose();
            con.Dispose();
        }

最佳答案

Do I need to use try-finally or the using-statement to dispose the SqlTransaction?


拥有它并没有什么坏处。这适用于每个实现 IDisposable 的类。 ,否则它不会实现这个接口(interface)。
但通常 garbage collector处理未引用的对象(这并不意味着GC调用dispose,isn't true),所以你只需要unmanaged resources .但是因为我也不想调用dispose在所有其他变量上或使用 using-statement在任何地方,研究类的实际实现总是值得的'Dispose方法。
SqlTransaction.Dispose :
protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        SNIHandle target = null;
        RuntimeHelpers.PrepareConstrainedRegions();
        try
        {
            target = SqlInternalConnection.GetBestEffortCleanupTarget(this._connection);
            if (!this.IsZombied && !this.IsYukonPartialZombie)
            {
                this._internalTransaction.Dispose();
            }
        }
        catch (OutOfMemoryException e)
        {
            this._connection.Abort(e);
            throw;
        }
        catch (StackOverflowException e2)
        {
            this._connection.Abort(e2);
            throw;
        }
        catch (ThreadAbortException e3)
        {
            this._connection.Abort(e3);
            SqlInternalConnection.BestEffortCleanup(target);
            throw;
        }
    }
    base.Dispose(disposing);
}
        
在不了解这里发生的所有(或任何事情)的情况下,我可以说这不仅仅是一个简单的 base.Dispose(disposing) .因此,确保处理 SqlTransaction 可能是一个好主意。
但是因为SqlConnection.BeginTransaction创建事务它也可能是一个好主意 reflect这也是:
public SqlTransaction BeginTransaction(IsolationLevel iso, string transactionName)
{
    SqlStatistics statistics = null;
    string a = ADP.IsEmpty(transactionName) ? "None" : transactionName;
    IntPtr intPtr;
    Bid.ScopeEnter(out intPtr, "<sc.SqlConnection.BeginTransaction|API> %d#, iso=%d{ds.IsolationLevel}, transactionName='%ls'\n", this.ObjectID, (int)iso, a);
    SqlTransaction result;
    try
    {
        statistics = SqlStatistics.StartTimer(this.Statistics);
        SqlTransaction sqlTransaction = this.GetOpenConnection().BeginSqlTransaction(iso, transactionName);
        GC.KeepAlive(this);
        result = sqlTransaction;
    }
    finally
    {
        Bid.ScopeLeave(ref intPtr);
        SqlStatistics.StopTimer(statistics);
    }
    return result;
}
如你看到的。 GC创建事务时,还将使连接保持事件状态。它也不包含对事务的引用,因为它只返回它。因此,即使连接已经被释放,它也可能不会被释放。处置交易的另一个论据。
您还可以查看 TransactionScope class这比 BeginTransaction 更安全.看看this question了解更多信息。

关于.net - SqlTransaction 是否需要调用 Dispose?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9525307/

相关文章:

c# - 错误: Unable to connect to any of the specified MySQL hosts

java - Hibernate 事务管理比较

c# - Winforms 处理 IDisposable

java - 在 "dispose()"内的 Music 对象上使用 "OnCompletionListener()"?

java - 使用 JOptionPane API 的自定义对话框不会被释放

c# - 使用 ninject.extensions.conventions 多次绑定(bind)服务

c# - XElement 仅添加前缀

.net - Mono 是否支持 XAML?

PHP MySqli 插入

php - 带有 try catch 的 PDO 事务语法