Reputation: 800
I've been Googling for an answer for the past few hours, but haven't found an answer, so I'm hoping someone here can point me in the right direction.
I am wondering how to do a dirty read with EF DbContext (Code-First) within a TransactionScope. For example
DbContext context = new MyEntities();
using(TransactionScope scope = new TransactionScope())
{
context.SomeTable.Add(someObject);
context.SaveChanges();
var objects = context.SomeTable.Where(...).Select(...); //times out here on the read, because the write above locks the tables
//modify each object
context.SaveChanges();
scope.Complete(); //transaction is a success only if the entire batch succeeds
}
I have tried wrapping the read call with the following:
using(TransactionScope scope2 = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions{IsolationLEvel = IsolationLevel.ReadUncommitted}))
{
var objects = context.SomeTable.Where(...).Select(...); //times out here on the
}
What is the proper approach?
Upvotes: 1
Views: 2624
Reputation: 174
You can set the IsolationLevel for TransactionScope like this...
var transactionOptions = new System.Transactions.TransactionOptions();
transactionOptions.Timeout = new TimeSpan(0, 0, 30);
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
using (var transactionScope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required, transactionOptions))
{
...
}
Upvotes: 1
Reputation: 171168
It has finally clicked for me what the problem is: EF is not integrating with TransactionScope
the way L2S nicely does. This means that EF opens and closes the connection for each operation requiring the server (saving changes or querying).
This gets you distributed transactions and a distributed deadlock.
To solve this, manually open and close the EF StoreConnection
to ensure that there is exactly one connection for the duration of the transaction.
Upvotes: 1
Reputation: 37354
You can just execute alter database your_db_name set READ_COMMITTED_SNAPSHOT on;
(available from SQLServer 2005) on the server, and readers won't be blocked by writters (assuming reading transaction in read committed
isolation level).
Upvotes: 0