Transactionscope VS Transaction in Linq to SQL

TransactionScope vs Transaction in LINQ to SQL

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.

Linq to SQL TransactionScope

We use LinqToSql and TransactionScope for multiple database transactions. You should really control your connection/context/transaction lifecycles if you're going to attempt it.

  • We control DataContext instances by the rule: If you new one up, you do that with a using statement.
  • We control connection lifecycles by the rule: If you open it, you must close it (but generally let the DataContext instances manage that).
  • We control transaction lifecycles by the rule: let DataContext manage what goes on in SubmitChanges and let TransactionScope manage what goes on within its using block.

Here's a code sample:

using (OuterDataContext outerDataContext = GetOuterDataContext())
{
using (InnerDataContext innerDataContext = GetInnerDataContext())
{
try
{
OuterRepository outerRepository = new OuterRepository();
// may read records into memory for updating/deleting.
outerRepository.WorkWithOuterRecords(outerRecords, outerDataContext);

InnerRepository innerRepository = new InnerRepository();
// may read records into memory for updating/deleting.
innerRepository.WorkWithInnerRecords(innerRecords, innerDataContext);

using (TransactionScope scope = new TransactionScope())
{
//starts a local tranaction in outerDB, held open by scope
outerDataContext.SubmitChanges();
//promotes the transaction to distributed, still held open by scope
innerDataContext.SubmitChanges();
// and done
scope.Complete();
}
}
catch (Exception ex)
{
LoggerClient.Log(ex);
response.Message = "It didn't save anything.";
}
}
}

TransactionScope transaction = new TransactionScope() VS TransactionScope s = context.Connection.BeginTransaction()

While Database. BeginTransaction() is used only for database related operations transaction, System. Transactions. ... TransactionScope for mixing db operations and C# code together in a transaction.

please see Below Links.Hope they help you:

TransactionScope vs Transaction in LINQ to SQL

Database.BeginTransaction vs Transactions.TransactionScope

linq to sql transaction

Wrap your code in a TransactionScope using block and then that will rollback unless it reaches the point where you call transactionScope.Complete().

Example:

using (TransactionScope transactionScope = new TransactionScope())
{
//code here
transactionScope.Complete();
}

Difference Between Transaction and TransactionScope

From msdn :

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. Due to its ease of use
and efficiency, it is recommended that
you use the TransactionScope class
when developing a transaction
application. When you instantiate
TransactionScope, the transaction
manager determines which transaction
to participate in
. Once determined,
the scope always participates in that
transaction. The decision is based on
two factors: whether an ambient
transaction is present and the value
of the TransactionScopeOption
parameter in the constructor. The
ambient transaction is the transaction
within which your code executes. You
can obtain a reference to the ambient
transaction by calling the static
Current property of the Transaction
class.

You can read more about that here :

http://msdn.microsoft.com/en-us/library/ms172152(v=vs.90).aspx

http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope(v=vs.90).aspx

Great (a bit old) article about transaction in .NET 2.0

http://msdn.microsoft.com/en-us/library/ms973865.aspx

How to rollback transaction using LINQ-to-SQL in entity framework?

There are two ways in which you can use transactions in entity framework. One using TransactionScope and another using database transaction.

For using database transaction, use the following code example:

using (dbDataContext db = new dbDataContext())
using (var dbContextTransaction = db.Database.BeginTransaction())
{
try
{
var user = new User(){ID = 1, Name = "Nick"};
db.Users.Add(user);
db.SaveChanges();
dbContextTransaction.Commit();
}
catch (Exception)
{
dbContextTransaction.Rollback();
}
}

And here's an example of EF's TransactionScope:

using (TransactionScope tranScope = new TransactionScope())
using (dbDataContext db = new dbDataContext())
{
try
{
var user = new User(){ID = 1, Name = "Nick"};
db.Users.Add(user);
db.SaveChanges();
tranScope.Complete();
}
catch(Exception ex){}
}

As you can see, you don't need to call any Roll-Back method in the case of TransactionScope. If you don't call the Complete() method, the transaction does not get committed and gets rolled back automatically before being disposed.

Unit of Work pattern vs. Transaction Scope for Linq-To-Sql?

I would definitely create some sort of centralized but externally-controlled transaction control. Personally, I favor UnitOfWork, because you can design it to be an abstract that is tied only to the Repository model and not to any implementation-specific details.

Currently, your unit of work is implementation-specific. Your developers know that the object named unitOfWork is actually a DataContext for Linq2SQL. Knowing that, they can bypass the Repository completely and use a UnitOfWork to make their DB calls. It would be a bad idea for them to do so, but the fact they can suggests a need to more fully encapsulate the specific details behind a better abstract.

I would make UnitOfWork a token class; the token is merely an abstract placeholder that refers to the atomic set of operations. Behind the scenes, you can use UnitsOfWork to key a collection of DataContexts, and use the Context for a particular UnitOfWork whenever that token is presented to the Repository by a calling method (it would be passed as a parameter). When the UnitOfWork is discarded by external code, dispose of the DataContext. Designing your Repository like this means that consuming code does not require any knowledge of the implementation details. If you later decide that Linq2SQL isn't meeting your needs and you want to switch to NHibernate, the changes end at the Repository boundary; your consuming code doesn't give a flying flip whether the UnitOfWork refers to a DataContext or an ISession.

Am I using TransactionScope and DataContext properly?

SubmitChanges will participate in the TransactionScope.

If SubmitChanges finds an ambient transaction it enlists to that transaction, otherwise it creates a transaction itself for the lifetime of the SubmitChanges method.

There is an MSDN Article about the transaction handling in SubmitChanges.

Using transactions with linq to entities

Try flipping your using clauses, and opening your connection before you start the transaction, and use the context to open the transaction. You also need to commit the transaction if your code is making updates.

using(var context = new XYZContext())
{
context.Database.Connection.Open();
using (TransactionScope s = context.Connection.BeginTransaction())
{

Int32 count = (from xyz in context.XYZs
where xyz.Name == "SameName"
select xyz.Name).Count();
Assert.AreEqual(count, 1);
s.Commit()
}
}

LINQ to SQL Transaction.Complete vs DataContext.SubmitChanges

SubmitChanges will send the DML statements. Commit will commit the transaction. While the transaction is not committed, other readers will not see your changes. You have no risk of saving partial changes or even making them visible for a shot period of time. You can call SubmitChanges multiple times. Without an explicit transaction SubmitChanges will use one internally.



Related Topics



Leave a reply



Submit