This answer does not interfere with simultaneous reading! This is not the right answer to this question!
Author here: I was wrong. I cannot delete this answer because it is an accepted answer. @Gilad, if you do not accept my answer, I will delete it.
Try the following:
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead })) { var newUrl = dbEntity.URLs.FirstOrDefault(url => url.StatusID == (int) URLStatus.New); if(newUrl != null) { newUrl.StatusID = (int) URLStatus.InProcess; dbEntity.SaveChanges(); } scope.Complete(); }
IsolationLevel.RepeatableRead apply the lock to all read lines so that Thread 2 cannot read from Table A if Table A was read by Thread 1 and Thread 1 did not complete the transaction. (According to the comments this is not so)
Just pay attention to TransactionScopes:
When you surround your code with TransactionScope , you are not creating any transactions, you are just creating an area in which a transaction may be required. When you read the insinde data in your using , the Entity Framework will create the transaction, but it will not be anymore, because now you are responsible for the transaction due to TransactionScope. That is: you define IsolationLevel, and you are responsible for committing or rolling back the transaction. By default, the isolation level will use write lock. That is, if I write a URL, it will block the table of URLs for reading and writing. To apply a read lock, you use IsolationLevel.RepeatableRead .
If you create more transactions inside your TransactionScope , it will be propagated to a distributed transaction, but that is beyond the scope of my answer.
Andrรฉ Pena Nov 15 '12 at 18:55 2012-11-15 18:55
source share