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?
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?
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();
}
}