私はSqlTransaction
を配置するtry-finally
またはusing
-statementを使用する必要がありますか?
それは傷ついていません。これはIDisposableを実装しているすべてのクラスに当てはまります。そうでなければ、このインタフェースを実装しません。
通常、ガベージコレクタは、オブジェクトがもはや参照されていない場合はそれを処理します。すべての第2変数に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は、トランザクションの作成時にもConnectionを有効に保ちます。それはそれが返すだけなので、トランザクションへの参照も保持しません。そのため、接続が既に行われていても、それを廃棄することはできません。トランザクションを破棄する別の引数。
さらに、BeginTransaction
よりもフェイルセーフであるTransactionScope
classを調べることもできます。詳細については、this questionをご覧ください。
それを持つことを傷つけることはありません。 – Brian
'sqlTrans'の周りに' using'を使用していない場合、明示的に 'Dispose()'を呼び出すことに傷つくことはありません。 –
@Cory sqlTrans.Dispose()を呼び出す前にsqlTransがすでに破棄されているかどうかを確認する必要がありますか? – Lijo