总的来说,我对 EF 和 SQL 还比较陌生,所以我需要一些帮助来澄清这一点。
假设我有一个表“钱包”(和 EF 代码第一个对象钱包),它有一个 ID 和一个余额。我需要做这样的操作:
if(wallet.balance > 100){
doOtherChecksThatTake10Seconds();
wallet.balance -= 50;
context.SaveChanges();
}
如您所见,它会检查条件是否有效,如果有效,则它必须首先执行一系列其他操作,这些操作需要很长时间(在这个夸张的示例中我们说 10 秒),然后如果有效通过它从钱包中减去 50 美元并保存新数据。
问题是,还有其他事情会随时改变钱包余额(这是一个网络应用程序)。如果发生这种情况:
- wallet.balance = 110;
- 此操作通过其“if”检查,因为 wallet.balance > 110
- 当它执行“doOtherChecksThatTake10Seconds()”时,用户从他们的钱包中转出 40 美元
- 现在 wallet.balance = 70
- “doOtherChecksThatTake10Seconds()”完成,从 wallet.balance 中减去 50,然后用新数据保存上下文。
在这种情况下,wallet.balance > 100 的检查不再为真,但由于延迟,操作仍然发生。我需要找到一种方法来锁定表格并且在整个操作完成之前不释放它,因此在此期间不会进行任何编辑。最有效的方法是什么?
应该注意的是,我已经尝试将这个操作放在 TransactionScope() 中,我不确定这是否会产生预期的效果,但我确实注意到它开始导致大量死锁,这是一个完全不同的数据库操作正在运行。
最佳答案
使用乐观并发 http://msdn.microsoft.com/en-us/data/jj592904
//Object Property:
public byte[] RowVersion { get; set; }
//Object Configuration:
Property(p => p.RowVersion).IsRowVersion().IsConcurrencyToken();
这允许脏读。但是,当您去更新记录时,系统会同时检查 rowversion 是否未更改,如果同时有人更改了记录,则会失败。 每次记录更改时,数据库都会维护行版本。
开箱即用的 EF 乐观锁定。
关于c# - 在 Entity Framework 中使用事务或锁定来确保正确操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18008065/