Reputation: 18087
I am using EF 6 and Code First
database solution in my application. The same application runs on several computers and access the same database. One Integer field in database is updated from these applications, the value of this field is reduced. The code is below and I think here could be race condition problem. How do you solve the problem in this situation?
public partial class CaContext
{
public override int SaveChanges()
{
var addedStatistics = ChangeTracker.Entries<Statistic>().Where(e => e.State == EntityState.Added).ToList().Select(p => p.Entity).ToList();
var testOrders = GetUser.Orders.First();
testOrders.Credits = testOrders.Credits - addedStatistics.Count; //Race condition here
return base.SaveChanges();
}
}
Upvotes: 0
Views: 1942
Reputation: 6248
Perform your operations inside of an Transaction Scope (possibly you have to set the correct isolation level). So just wrap up the SaveChanges() Call into an transaction scope:
public void method() {
using(var transactionScope = new TransactionScope()) {
_context.SaveChanges();
}
}
You will find more here: http://msdn.microsoft.com/en-us/data/dn456843#transactionScope
Upvotes: 0
Reputation: 4159
I would look at the overall design and remove such counter. For example, you can create a table, where you will add a new record everytime you save changes. You set the count there and then with a SUM query you get the total. This will eliminate the problem.
If you really want to have such one field, than you can create a stored proc and call it. SP will be run on database and will have synchronized access to data.
Upvotes: 0
Reputation: 25743
One option would be to perform an update statement that decrements the value instead of doing a read, calculate, write.
Database.SqlCommand(
@"UPDATE [CreditCount]
SET [Credits] = [Credits] - x
WHERE [UserID] = y"
);
Upvotes: 2