Asp.net web api + Entity Framework : multiple requests cause data conflict

标签 asp.net sql asp.net-mvc entity-framework

我正在使用 VS2013、EF6.02 和 Web API 2 开发应用程序。我正在使用 ASP.NET SPA 模板,并针对由 sql server 支持的 Entity Framework 数据源创建 RESTful api。 (在开发中,这驻留在 SQL Server 本地实例上。)

到目前为止,我有两个 API 方法(一个只读取数据,一个写入数据),我正在通过在 javascript 中调用它们来测试它们。当我在我的脚本中只调用一个方法时,任何一个都可以完美地工作。但是如果我在脚本中同时调用它们(不等待任何一个的回调触发),我会在调试器中得到不好的结果和不同的异常。一些异常表明由于存在未决事务而无法完成保存。另一个异常说明了与其他线程的冲突。有时,在尝试读取结果集时,读取操作会因空指针异常而失败。

“不允许新事务,因为 session 中还有其他线程在运行。”

这让我怀疑我是否正确地为每个请求获取了一个新的 DBContext。我的代码如下:

    static Startup()
    {
        context = new Data.SqlServer.AppDbContext();
  ...
    }

然后每当实例化一个工作单元时,我都会访问 Startup.context。

我尝试实现工作单元模式,每个请求共享一个 UOW 对象,该对象具有一个 DBContext 对象。

我的问题:我是否有额外的责任来确保网络请求彼此“很好地配合”?我希望这是其他人已经处理过的问题。也许我看到的错误是合法的,因为如果一个用户的数据被触及,它暂时处于无效状态,如果其他请求恰好在那个时刻进入,它们确实会失败(我应该编码预期这些失败)。我想即使每个请求都有自己的 DBContext,它们仍然共享相同的底层 SQL 数据源,所以这可能会导致问题。

我可以尝试组合一个测试用例,但我会得到不同的行为,具体取决于我放置断点的位置以及我在断点上花费的时间,向我重申这是与时间相关的。

感谢任何帮助或建议... -本

最佳答案

您的问题在于设置上下文的位置。 Startup 方法用于整个应用程序启动时,因此发出的任何请求都将使用相同的上下文。这不是按请求设置,而是按应用程序设置。至于为什么会出现错误,EntityFramework NOT 是线程安全的。由于 IIS 生成许多线程来处理并发请求,因此您的单个 context 正在跨多个线程使用。

至于解决方案,你可以看看

-依赖注入(inject)框架(例如 NinjectUnity )

-在您的 UnitOfWork 类中放置一个 using 语句

using(var context = new Data.SqlServer.AppDbContext()){//do stuff}

-或者,我看到有人创建一个类来获取该请求的上下文并将其存储在 HttpContext.Cache[] 元素中(使用唯一名称以便您可以轻松地在另一个类中检索它),使得这样您就可以为相同的请求重用相同的上下文。像这样:

public AppDbContext GetDbContext()
    {
        var httpContext = HttpContext.Current;
        if (httpContext == null) return new AppDbContext();
        const string contextTypeKey = "AppDbContext";
        if (httpContext.Items[contextTypeKey] == null)
        {
            httpContext.Items.Add(contextTypeKey, new AppDbContext());
        }
        return httpContext.Items[contextTypeKey] as AppDbContext;
    }

要使用上述方法,只需调用 var context = GetDbContext();

注意

以上方法我们都有,但这里专门针对第三种方法。它似乎适用于两个警告。首先,不要在 using 语句中使用它,因为在请求范围内它对任何其他类都不可用(你处置它)。其次,确保您对 Application_EndRequest 的调用确实确实处理了它。我们看到这些小错误在请求结束后在内存中徘徊,导致内存使用量激增。

关于Asp.net web api + Entity Framework : multiple requests cause data conflict,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20729910/

相关文章:

具有 1 个以上工作进程的 Asp.net 应用程序

c# - 从表单数据创建 PDF 并保存

mysql - 为什么相同的查询给出两个不同的结果?

asp.net-mvc - 在ASP.NET MVC表单上禁用非侵入式验证

javascript - 在 ASPX 页面中使用脚本

c# - JQuery 从 aspx 页面中获取数据

sql - 如何使用 Windows 身份验证登录 SQL Server

mysql - 从 MySQL 表中的值中删除百分号

javascript - 使用 MVC、C# 和 AngularJS 时如何在页面加载时保留页面的下拉值?

asp.net-mvc - 在 asp.net mvc 中作为单个项目实现的区域与作为多个项目实现的区域有何优缺点