views:

88

answers:

1

Hi just reading about using transaction scrope, previously I am used to making transactions inside a single DB class like

try
            {
                con.Open();
                tran = con.BeginTransaction();
                OleDbCommand myCommand1 = new OleDbCommand(query1, con);
                OleDbCommand myCommand2 = new OleDbCommand(query2, con);
                myCommand .Transaction = tran;
                // Save Master
                myCommand1.ExecuteNonQuery();

                // Save Childred
                myCommand2.ExecuteNonQuery();

                // Commit transaction 
                tran.Commit();

            }
catch (OleDbException ex)
                {
                    tran.Rollback();
                    lblError.Text = "An error occured " + ex.ToString();
                }

                finally
                {
                    if (con != null)
                    {
                        con.Close();
                    }

                }

But now I come to know that I can execute transaction inside the Business Logic layer simply by using a transaction scope object and using separate DB classes like

   public static int Save(Employee myEmployee)
    {
      using (TransactionScope myTransactionScope = new TransactionScope())
      {
        int RecordId = EmpDB.Save(myEmployee);

        foreach (Address myAddress in myEmployee.Addresses)
        {
          myAddress.EmployeeId = EmployeeId;
          AddressDB.Save(myAddress);
        }

        foreach (PhoneNumber myPhoneNumber in myEmployee.PhoneNumbers)
        {
          myPhoneNumber.EmployeeId = EmployeeId;
          PhoneNumberDB.Save(myPhoneNumber);
        }

        myTransactionScope.Complete();

        return EmployeeId;
      }
    }

Which one is the recommended coding practice and why ? Is using a Transaction Scope safe ? Is it the latest way to do things ? I am confused about both methods.

Thanks in advance.

+1  A: 

One of the nice things about Transaction scope is that you don't need the try/catch block. You just have to call Complete on the scope in order to commit the transaction, and it rollsback automatically if an exception does occur.

You can also use other components that are able to participate in transactions, not just the DB connection. This is because the components (including the connection) look for a Transaction on the current thread. It is this transaction that is created by the call to

using (TransactionScope myTransactionScope = new TransactionScope())
Daniel Dyson
Thanks Daniel Dyson. That seems super easy and one has to code so less. If each DB layer function Address.Save();, Email.Save();, Employee.Save(); have their own connections and commands, would it work flawlessly? Like in my 2nd example.
Popo
Sorry, that is a difficult thing to answer straight awy without testing. The good news is that it should be easy to test.
Daniel Dyson
It would be but which one is the recommended practice and why ?
Popo
Transaction Scope is cleaner code and provides the ability to include other components int othe scope, whereas the con.BeginTransaction doesn't. That is enough reason for me to use it. The actual DB Transaction sent down the wire to the DB is the same in this case, but who knows what you might want to add to the transaction in the future, such as logging to another db or sending an email.
Daniel Dyson
Thanks for the info, will it commit the data if stored procedures are used in each DB class with a COMMIT in end ? Or would it just roll back in case of failure independent of the stored procedure's instructions ?
Popo