Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does transactionscope get properly disposed?

I'm finding a possible issue in our code base where the developer forgot to wrap the contents of a using statement with curley braces:

        using (TransactionScope transactionScope = new TransactionScope(Transaction.Current))
            try
            {
                RecordUserConnectionCore(context, userName);
                transactionScope.Complete();
            }
            catch
            {
                transactionScope.Dispose();
                throw;
            }

Does the try/catch get executed inside of the using statement? Is the transactionScope properly disposed?

Please note that this question is in regards to wether the try/catch block is executing inside of the using context. I ask because there are no braces surrounding the try/catch code.

like image 870
Alex Gordon Avatar asked Oct 19 '25 13:10

Alex Gordon


2 Answers

After re-reading, I realized that I missed the actual question.

Yes, the try/catch is "within" the using block, even though the using statement doesn't have braces.

If a block doesn't have braces, then implicitly the block only includes the very next statement or block.

So using another example, you could do this:

if(x = 1)
{
    try{}
    catch{}
}

or this

if(x=1)
try{}
catch{}

and both are exactly the same.

For readability, I'll usually add the braces anyway. I think it's a little bit clearer and someone who doesn't know that detail of syntax won't be confused.


Yes, in your code the TransactionScope always gets disposed.

By putting it in a using block and calling Dispose, Dispose gets called twice if there's an exception. It gets called once in the catch block and again with the end of the using block. (That won't throw an exception, but it's unnecessary.)

The using block means that transactionScope already gets disposed even if there's an exception. So you could just do this:

using (TransactionScope transactionScope = new TransactionScope(Transaction.Current))
{
    RecordUserConnectionCore(context, userName);
    transactionScope.Complete();
}
like image 158
Scott Hannen Avatar answered Oct 22 '25 03:10

Scott Hannen


The Try/Catch is executing inside of the using block. Your code is exactly the same as if you had the following:

using (TransactionScope transactionScope = new TransactionScope(Transaction.Current))
{
      try
      {
           RecordUserConnectionCore(context, userName);
           transactionScope.Complete();
      }
      catch
      {
          transactionScope.Dispose();
          throw;
      }
}

One of the reasons you can know that this is true is because the

transactionScope.Dispose(); 

line compiles.

like image 39
JBdev Avatar answered Oct 22 '25 03:10

JBdev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!