Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TransactionScope vs Transaction in LINQ to SQL

What are the differences between the classic transaction pattern in LINQ to SQL like:

using(var context = Domain.Instance.GetContext()) {     try     {         context.Connection.Open();         context.Transaction = context.Connection.BeginTransaction();         /*code*/         context.Transaction.Commit();     }     catch     {         context.Transaction.Rollback();     }          } 

vs the TransactionScope object

using (var context = Domain.Instance.GetContext()) using (var scope = new TransactionScope()) {     try     {         /*code*/         scope.Complete();     }     catch     {     } } 
like image 714
Ben McNiel Avatar asked Feb 12 '09 17:02

Ben McNiel


People also ask

What is TransactionScope in Entity Framework?

Transactions namespace was used to handle transactions in the Entity Framework using TransactionScope and the Entity Framework uses this transaction to save the changes in the database. using (TransactionScope scope = new TransactionScope()) { //Code Here.

What is the use of TransactionScope in C#?

The TransactionScope class provides a simple way to mark a block of code as participating in a transaction, without requiring you to interact with the transaction itself. A transaction scope can select and manage the ambient transaction automatically.


2 Answers

It should be noted that when using the TransactionScope there is no need for the try/catch construct you have. You simply have to call Complete on the scope in order to commit the transaction when the scope is exited.

That being said, TransactionScope is usually a better choice because it allows you to nest calls to other methods that might require a transaction without you having to pass the transaction state around.

When calling BeginTransaction on the DbConnection object, you have to pass that transaction object around if you want to perform other operations in the same transaction, but in a different method.

With TransactionScope, as long as the scope exists, it will handle everything that registers with the current Transaction on the thread, making your code cleaner, and more maintainable.

On top of that, you have the added benefit of being able to use other resources that can participate in transactions, not just the connection to the database.

It should be noted that in situations where you need to squeeze the most out of your connections and database operations, you might not want to use TransactionScope; even against a single database, you run the possibility of the Distributed Transaction Coordinator being used and having the transaction being turned into a distributed transaction (even for a single database connection).

In these cases, while muddying up your design, you might want to consider passing a connection-specific transaction around.

Or, if you know you will use one resource consistently (and on the same thread), you might want to create a class that reference-counts your connection/transaction.

You would create a class that on construction, creates your resource/increments the count. It would also implement IDisposable (in which you would decrement/release/commit/abort when the count is zero), and store the count in a variable that has ThreadStaticAttribute applied to it.

This allows you to separate the transaction management from the logic code, and still hold onto a singular resource fairly efficiently (instead of escalating to a distributed transaction).

like image 112
casperOne Avatar answered Sep 18 '22 15:09

casperOne


Linq2SQL will use an implicit transaction. If all of your updates are done within a single Submit, you may not need to handle the transaction yourself.

From the documentation (emphasis mine):

When you call SubmitChanges, LINQ to SQL checks to see whether the call is in the scope of a Transaction or if the Transaction property (IDbTransaction) is set to a user-started local transaction. If it finds neither transaction, LINQ to SQL starts a local transaction (IDbTransaction) and uses it to execute the generated SQL commands. When all SQL commands have been successfully completed, LINQ to SQL commits the local transaction and returns.

like image 42
TGnat Avatar answered Sep 17 '22 15:09

TGnat