【发布时间】:2017-12-06 16:13:59
【问题描述】:
我有一个几乎同时接收几个请求的 Web 服务。
如果发生这种情况,两个请求的事务就会死锁,我必须回滚重新运行它们。
using (var context = new DbContext())
using (var dbContextTransaction = context.Database.BeginTransaction(IsolationLevel.Serializable))
{
var subscription = context.Subscriptions.FirstOrDefault(x => x.Provider == provider);
if (subscription == null)
{
*/Insert*/
}
else
{
/*Update*/
}
context.SaveInTransaction(null);
dbContextTransaction.Commit();
}
据我了解,这两个请求都输入了事务并阅读了订阅表。当它们准备好提交时,它们就死锁了,因为它们无法在另一个事务(IsolationLevel.Serializable)读取的数据范围内插入值。
如果我不使 TransactionLevel 可序列化,则其中一个请求无法满足提供者列的唯一约束并被回滚。
我应该怎么做才能防止死锁?
【问题讨论】:
-
要么捕获表示唯一违规的异常并重试,要么使用原始sql在一个原子操作中执行“upsert”(在sql server中对应的操作是MERGE)。我不知道在 EF 中处理该问题的其他方法。
标签: c# sql-server entity-framework transactions