title: Nested TransactionScope() won't roll back
body: <p>I am trying to make use of nested transactions in C# for the first time. In the past I've always wrapped my <code>SqlCommands</code> inside <code>SqlTransactions</code> inside <code>SqlConnections</code>. Something like this:</p>
  
  <pre><code>using (SqlConnection myCon = new SqlConnection(...))    
      using (SqlTransaction myTran = myCon.BeginTransaction())
      {
          using (SqlCommand myCom1 = new SqlCommand("...", myCon, myTran))
          {
              ...
          }       
          using (SqlCommand myCom2 = new SqlCommand("...", myCon, myTran))
          {
              ...
          }
          .
          .
          .
          myTran.Commit();
      }
  }
  </code></pre>
  
  <p>All of this, with the necessary <code>try...catch</code> handling of course so if an exception occurs anywhere inside the <code>SqlTransaction</code>, I know that none of the <code>SqlCommands</code> will be committed.</p>
  
  <p>So I thought I'd give TransactionScope a try but it's not working. Here's what I'm doing; I have two transactions, one after the other, but both inside an outer transaction. Depending on which checkbox had been checked on the form, the code throws an exception either:
  1. just before the first inner transaction's commit, or
  2. between the two inner transactions, or
  3. just before the second inner transaction's commit, or
  4. just before the outer transaction's commit</p>
  
  <p>The problem I'm getting is that, regardless of which checkbox I tick, the code executes as if no transactions were present. So in other words, the fact that I bug jump out of the try block because of an exception doesn't roll back any of the transactions.</p>
  
  <p>Would appreciate some help. Below is my code for the little test application.</p>
  
  <pre><code>try
  {
      using (SqlConnection sqlConnection = new SqlConnection(connectionString))
      {
          sqlConnection.Open();
  
          using (TransactionScope transactionOuter = new TransactionScope())
          {
              using (TransactionScope transactionInner1 = new TransactionScope())
              {
                  using (SqlCommand sqlCommand = new SqlCommand("INSERT INTO BasicTable (Value) VALUES ('Inside Inner Transaction 1')", sqlConnection))
                  {
                      sqlCommand.ExecuteNonQuery();
                  }
  
                  if (checkBox_FailInner1.Checked)
                      throw (new Exception("Failed inside inner transaction 1"));
  
                  transactionInner1.Complete();
              }
  
              if (checkBox_FailBetween.Checked)
                  throw (new Exception("Failed between inner transactions"));
  
              using (TransactionScope transactionInner2 = new TransactionScope())
              {
                  using (SqlCommand sqlCommand = new SqlCommand("INSERT INTO BasicTable (Value) VALUES ('Inside Inner Transaction 2')", sqlConnection))
                  {
                      sqlCommand.ExecuteNonQuery();
                  }
  
                  if (checkBox_FailInnner2.Checked)
                      throw (new Exception("Failed inside inner transaction 2"));
  
                  transactionInner2.Complete();
              }
  
              if (checkBox_FailOuter.Checked)
                  throw (new Exception("Failed before outer transaction could commit"));
  
              transactionOuter.Complete();
          }
      }
  }
  catch (Exception exc)
  {
      MessageBox.Show(exc.Message);
  }
  
  MessageBox.Show("Done");
  </code></pre>