我有以下使用SqlTransaction的代码。我已经在catch中调用dispose并最终阻止了..但是在调用Dispose()之前我还没有检查它是否已经处理掉了。在调用Dispose()之前,我们如何检查SqlTransaction是否已被释放?
我已提到MSDN:SqlTransaction.Dispose Method。但这并不包括我的问题。
同时提到http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.dispose(v=vs.100).aspx
注意:我已经知道TransactionScope
优于SqlTransaction
。但我试图了解SqlTransaction的配置。
CODE
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlTransaction transaction = null;
try
{
transaction = connection.BeginTransaction();
sessionID = GetSessionIDForAssociate(connection, empID, transaction);
//Other code
//Commit
transaction.Commit();
}
catch
{
//Rollback
if (transaction != null)
{
transaction.Rollback();
transaction.Dispose();
}
//Throw exception
throw;
}
finally
{
if (transaction != null)
{
transaction.Dispose();
}
}
答案 0 :(得分:8)
我们如何检查之前是否已经处理过SqlTransaction 调用Dispose()?
你不必。两次调用处置不会对您造成任何问题。
如果对象的Dispose方法被多次调用,则该对象 必须忽略第一个之后的所有呼叫。该对象不得抛出 如果多次调用Dispose方法,则会出现异常。例 Dispose以外的方法可以在何时抛出ObjectDisposedException 资源已经处理完毕。
但是如果你只想调用Dispose一次,那么你可以使用布尔标志来设置事务处理时间,也可以将其设置为null。或者在catch
块中删除要处置的调用,因为始终会调用finally
块。
由于SqlTransaction实现IDisposable,如果你使用块则更好。类似的东西:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlTransaction transaction = connection.BeginTransaction())
{
try
{
sessionID = GetSessionIDForAssociate(connection, empID, transaction);
//Other code
//Commit
transaction.Commit();
}
catch
{
//Rollback
if (transaction != null)
{
transaction.Rollback();
}
//Throw exception
throw;
}
}
}
由于使用块行为类似于try/finally
块,因此它将确保在事务完成时处理事务(即使发生异常)。因此,您无需手动拨打Dispose
。
答案 1 :(得分:2)
在调用dispose之后添加transaction=null
,然后您的现有测试将起作用。
答案 2 :(得分:2)
为什么要查看是否已经处理过?您可以通过简单地省略Dispose
块中的来电来避免致电catch
两次:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlTransaction transaction = null;
try
{
transaction = connection.BeginTransaction();
sessionID = GetSessionIDForAssociate(connection, empID, transaction);
//Other code
//Commit
transaction.Commit();
}
catch
{
//Rollback
if (transaction != null)
{
// No need to dispose here - finally is always called
transaction.Rollback();
}
//Throw exception
throw;
}
finally
{
if (transaction != null)
{
// Always called, so no need to dispose elsewhere.
transaction.Dispose();
}
}
答案 3 :(得分:2)
从catch块中删除.Dispose()
调用。最后总是被执行,所以这样你就会尝试两次处理交易。
它没有回答“我怎么知道它是否已被处置”,但可能解决了你的问题。