【问题标题】:Entity Framework Core read un-commited issue实体框架核心读取未提交的问题
【发布时间】:2018-07-01 04:39:32
【问题描述】:

我们的一个内部应用程序中有一个相当重的模块,它使用 SignalR 检查新通知。我们被告知我们正在数据库上创建锁,并且我们应该对有问题的方法进行未提交的读取。

这不是我以前必须做的事情,据我所知,EF 默认情况下会提交对记录的读取。因此,我将现有查询包装在另一个 using 语句中,如下所示:

    public IEnumerable<ClientUpdates> GetNotifications(int forPaId)
    {
        using (var transactionScope =
            new TransactionScope(TransactionScopeOption.Required, GetReadUncommitedTransactionOptions()))
        {
            using (var ctx = ContextFactory.CompanyDb)
            {
               // Do stuff

                transactionScope.Complete();

                return objectList;

            }
        }
    }

    private TransactionOptions GetReadUncommitedTransactionOptions()
    {
        var transactionOptions = new TransactionOptions
        {
            IsolationLevel = IsolationLevel.ReadUncommitted
        };

        return transactionOptions;
    }

这会导致以下错误消息:

InvalidOperationException: 警告作为警告的错误异常 'Microsoft.EntityFrameworkCore.Database.Transaction.AmbientTransactionWarning': 已检测到环境事务。实体框架核心 不支持环境事务。看 http://go.microsoft.com/fwlink/?LinkId=800142 压制这个 异常使用 DbContextOptionsBuilder.ConfigureWarnings API。 覆盖时可以使用 ConfigureWarnings DbContext.OnConfiguring 方法或使用 AddDbContext 上 应用服务提供商。

因此我试图抑制警告:

services.AddDbContext<DbContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("MyConnectionString"));
            options.ConfigureWarnings(x => x.Ignore(RelationalEventId.AmbientTransactionWarning));
        });

这会导致此错误消息:

NotSupportedException:在环境事务中登记不是 支持。

所以现在我有点迷茫,我可以看到其他人已经在official issue tracker 上记录了这个问题,但我不明白实际问题是什么,以及如何强制这个特定模块执行“ Dirty” 读取数据,从而阻止锁的发生。

【问题讨论】:

    标签: c# entity-framework-core asp.net-core-2.0


    【解决方案1】:

    首先,您得到的建议有点过时。自 SQL Server 2005 以来,数据库快照已启用无需锁定的查询。这应该是默认设置,但我想它可能已被关闭。要进一步调查,请参阅relevant documentation。总而言之,只要启用此功能,您就不必担心您的查询会创建锁。

    其次,EF Core 中存在一个错误,该错误当前会阻止您使用的代码。然而,它已经被修复了,但它仍然在上游(即它还没有推出)。基本上,您目前无法执行此操作,但您很快就能做到。如果第一个解决方案不起作用,我会说只是等待。

    最后,假设第一个解决方案由于某种原因对您不起作用并且您绝对不能等待修复推出,您始终可以简单地为使用 NOLOCK 的查询创建一个或多个存储过程。这当然是一项更加手动的工作,所以我会先从您最繁重的查询开始。在之前和之后分析查询,您还可以考虑进行一些负载测试,以确保您确实为自己购买了一些东西。

    【讨论】:

      猜你喜欢
      • 2016-11-27
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 2021-08-23
      • 1970-01-01
      • 2021-12-27
      • 2020-11-29
      相关资源
      最近更新 更多