下面的代码使用SqlTransaction。我叫了dispose in catch,最后阻止了..但是,在调用Dispose()之前,我还没有检查它是否已经被释放。如何在调用Dispose()之前检查SqlTransaction是否已被释放?
我已经提到MSDN:SqlTransaction.Dispose法了。但这不包括我的问题。
还提到了http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.dispose(v=vs.100).aspx
注意:我已经知道TransactionScope比SqlTransaction具有优势。但我想了解SqlTransaction的处置。
码
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();
}
}发布于 2013-01-21 12:42:35
如何在调用Dispose()之前检查SqlTransaction是否已被释放?
你不需要这么做。打两次电话不会给你带来任何问题。
Dispose - MSDN
如果一个对象的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。
发布于 2013-01-21 12:38:33
在调用dispose之后添加transaction=null,那么现有的测试就可以工作了。
发布于 2013-01-21 12:40:36
你为什么要检查它是否已经处理好了?只需从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();
}
}https://stackoverflow.com/questions/14438736
复制相似问题