I have following code that uses SqlTransaction. I have called dispose in catch and finally blocks.. But I have not checked whether it is already disposed before calling Dispose(). How can we check whether the SqlTransaction is already disposed before calling Dispose()?
I have referred MSDN:SqlTransaction.Dispose Method. But that does not cover my question.
Also referred http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.dispose(v=vs.100).aspx
Note: I already know that TransactionScope
has advantages over SqlTransaction
. But I am trying to understand the SqlTransaction’s dispose.
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();
}
}
How can we check whether the SqlTransaction is already disposed before calling Dispose()?
You don't have to. Calling dispose twice won't cause you any problem.
Dispose - MSDN
If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.
But if you want to only call Dispose once then you can either use a boolean flag to set when the transaction is disposed or you can set it to null. Or remove the call to dispose in catch
block since finally
block will always be called.
Since SqlTransaction implements IDisposable, its better if you use it with using block. Something like:
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;
}
}
}
Since using block acts like try/finally
block, and it will ensure the disposal of the transaction upon its completion (even if the exception occurs). So you don't have to manually call Dispose
.
Add transaction=null
after you call dispose and then your existing tests will work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With