BeginTransaction vs TransactionScope

2

I was reviewing this answer and the question came up:

What is the difference between BeginTransaction and TransactionScope ? Are there specific situations for each? What are its advantages and disadvantages compared to each other?

    
asked by anonymous 09.06.2016 / 13:27

1 answer

1

Jedals, if you are using Entity Framework 5 version or earlier, you will have to use TransactionScope if you want to use a single transaction for more than one operation.

From EF6 , it has incorporated the BeginTransaction and UseTransaction methods to the Database property, so it is possible to reuse the same transaction in more than one operation.

Another change in EF6 is that it accepts an already open connection, so we can call sqlConnection.BeginTransaction and then pass this connection as argument at DbContext initialization.

Another point is about Assyrian operations, in case your targetFramework will be a version prior to 4.5.1 , then TransactionScope will not work, so its only option is BeginTransaction

For most scenarios, BeginTransaction is more than sufficient, and there is no need for a TransactionScope , but it is easier to work with TransactionScope in two scenarios.

Distributed Transactions

If your transaction involves more than one connection, TransactionScope will convert your local transaction into a distributed transaction automatically.

Recources Volateis

BeginTransaction keeps your transaction only at the Bando de Dados level, if you need to have an object in memory also suffer a Rollback / Commit , this object can implement the IEnlistmentNotification interface and be added to the transaction .

follows an example taken from MSDN

static void Main(string[] args)
{
    try
    {
        using (TransactionScope scope = new TransactionScope())
        {

            //Create an enlistment object
            myEnlistmentClass myElistment = new myEnlistmentClass();

            //Enlist on the current transaction with the enlistment object
            Transaction.Current.EnlistVolatile(myElistment, EnlistmentOptions.None);

            //Perform transactional work here.

            //Call complete on the TransactionScope based on console input
            ConsoleKeyInfo c;
            while(true)
            {
                Console.Write("Complete the transaction scope? [Y|N] ");
                c = Console.ReadKey();
                Console.WriteLine();

                if ((c.KeyChar == 'Y') || (c.KeyChar == 'y'))
                {
                    scope.Complete();
                    break;
                }
                else if ((c.KeyChar == 'N') || (c.KeyChar == 'n'))
                {
                    break;
                }
            }
        }
    }
    catch (System.Transactions.TransactionException ex)
    {
        Console.WriteLine(ex);
    }
    catch
    {
        Console.WriteLine("Cannot complete transaction");
        throw;
    }
}

class myEnlistmentClass : IEnlistmentNotification
{
    public void Prepare(PreparingEnlistment preparingEnlistment)
    {
        Console.WriteLine("Prepare notification received");

        //Perform transactional work

        //If work finished correctly, reply prepared
        preparingEnlistment.Prepared();

        // otherwise, do a ForceRollback
        preparingEnlistment.ForceRollback();
    }

    public void Commit(Enlistment enlistment)
    {
        Console.WriteLine("Commit notification received");

        //Do any work necessary when commit notification is received

        //Declare done on the enlistment
        enlistment.Done();
    }

    public void Rollback(Enlistment enlistment)
    {
        Console.WriteLine("Rollback notification received");

        //Do any work necessary when rollback notification is received

        //Declare done on the enlistment
        enlistment.Done();
    }

    public void InDoubt(Enlistment enlistment)
    {
        Console.WriteLine("In doubt notification received");

        //Do any work necessary when indout notification is received

        //Declare done on the enlistment
        enlistment.Done();
    }
}
    
09.06.2016 / 14:32