【问题标题】:Using READ_COMMITTED_SNAPSHOT with EF code first 5将 READ_COMMITTED_SNAPSHOT 与 EF 代码一起使用 5
【发布时间】:2013-07-08 14:21:58
【问题描述】:

最近,我们的用户有时会遇到超时过期错误,当他们想要更新数据库上的某些记录时。(我认为数据库中会出现死锁之类的情况) 我们的DataBase是SQL Server 2008 R2,我们的应用是EF5代码先开发出来的。

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

1- 在 DB 中激活 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();
}

此示例使用了TransactionScop 语句。但我们没有使用TransactionScop 来管理Transactions。例如我们的模型中有继承,当我们调用.SaveChange()时,EF创建和管理Transaction本身。

有什么方法可以使用READ_COMMITTED_SNAPSHOT而不使用TransactionScop 语句?

【问题讨论】:

  • 从我的测试来看,如果你在 TransactionOptions 中设置了 IsolationLevel.Snapshot,它将覆盖数据库设置,事务将在 Snapshot 下执行隔离级别,而不是 ReadCommittedSnapshot

标签: c# sql-server-2008 entity-framework transactions database-deadlocks


【解决方案1】:

READ_COMMITTED_SNAPSHOT 和 SNAPSHOT_ISOLATION 不是一回事。在数据库上启用READ_COMMITTED_SNAPSHOT 后,所有READ COMMITTED 事务都将使用它。

SNAPSHOT_ISOLATION 是完全不同的隔离级别,需要像你一样在代码中调用。

进一步阅读: https://msdn.microsoft.com/en-us/library/tcbchxcb(v=vs.110).aspx

【讨论】:

    【解决方案2】:

    您可以在没有TransactionScope 的情况下开始交易,为此请使用DbContext 的Connection 属性:

    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);
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-06
      • 2021-07-11
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      • 2010-11-06
      • 1970-01-01
      • 2015-05-31
      • 2012-11-06
      相关资源
      最近更新 更多