我需要在 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 theusing
-statement to dispose theSqlTransaction
?
拥有它并没有什么坏处。这适用于每个实现 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/