Is the transaction appliance actually configured correctly?

I find a possible problem in our codebase where the developer forgot to wrap the contents of the statement using

with curly braces:

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

      

Is try / catch being attempted inside a using statement?

Note that this question is about the try / catch block being executed within the context of use. I am asking if there are no parentheses associated with the try / catch code.

+3


source to share


2 answers


Try / Catch is executed inside the use 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 may know this to be true is that



transactionScope.Dispose(); 

      

...

+1


source


After reading it over again, I realized I was missing the real question.

Yes, it try/catch

is inside a block using

, although the operator using

does not have curly braces.

If there are no curly braces in the block, then implicitly the block contains only the next statement or block.

So, using another example, you can do this:

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

      

or

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

      



both are the same.

For readability, I'll usually add curly braces. I think this is a little clearer, and someone who doesn't know the syntax details don't get confused.


Yes, in your code TransactionScope

it is always removed.

By placing it in a block using

and calling it Dispose

, it Dispose

gets called twice if there is an exception. It is called once in the block catch

and again with the end of the block using

. (This won't throw an exception, but it doesn't need to.)

Block using

means it is TransactionScope

already being removed, even if there is an exception. Therefore, you can simply do this:

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

      

+2


source







All Articles