使用EF Code First 5和READ_COMMITTED_SNAPSHOT

4

最近,我们的用户在更新某些数据库记录时有时会遇到超时过期错误(我认为这类似于数据库死锁)。我们的数据库是SQL Server 2008 R2,应用程序使用EF5代码优先开发。

今天,我阅读了一篇关于在SQL Server中使用READ_COMMITTED_SNAPSHOT选项的文章,我认为这个选项可以帮助我们预防数据库死锁。根据该文章,它有两个步骤:

1- 在数据库中启用READ_COMMITTED_SNAPSHOT

ALTER DATABASE testDatabase SET ALLOW_SNAPSHOT_ISOLATION ON;
ALTER DATABASE testDatabase SET READ_COMMITTED_SNAPSHOT ON;

2- 在代码中使用READ_COMMITTED_SNAPSHOT选项:

using (var transactionScope =
new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel= IsolationLevel.Snapshot }))
{
  // update some tables using entity framework  
  context.SaveChanges();  
  transactionScope.Complete();
}

这个示例中使用了TransactionScope语句。但我们没有使用TransactionScope来管理Transactions。例如,我们的模型中有继承关系,当我们调用.SaveChange()时,EF会自行创建和管理Transaction

有没有办法在不使用TransactionScope语句的情况下使用READ_COMMITTED_SNAPSHOT


2
根据我的测试,如果在TransactionOptions中设置_IsolationLevel.Snapshot_,它将覆盖数据库设置,并且事务将在_Snapshot_隔离级别下执行,而不是_ReadCommittedSnapshot_。 - thepirat000
2个回答

6
READ_COMMITTED_SNAPSHOTSNAPSHOT_ISOLATION 不是同一个东西。当你在数据库上启用READ_COMMITTED_SNAPSHOT后,所有的READ COMMITTED事务都会使用它。 SNAPSHOT_ISOLATION 是完全不同的隔离级别,需要像你现在做的那样在代码中显式调用。
更多阅读: https://msdn.microsoft.com/en-us/library/tcbchxcb(v=vs.110).aspx

0

您可以在不使用TransactionScope的情况下开始事务,只需使用DbContextConnection属性即可:

public static DbTransaction BeginTransaction(this DbContext context, IsolationLevel isolationLevel)
{
    if (context.Database.Connection.State != ConnectionState.Open)
        context.Database.Connection.Open();
    return context.Database.Connection.BeginTransaction(isolationLevel);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接