本文介绍了当我使用EF(和WebAPI)向我的数据文本发送高频请求时,出现奇怪的竞争条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  [HttpDelete] 
public HttpResponseMessage DeleteFolder(int id)
{
_service.DeleteFolder(id);
return Request.CreateResponse(HttpStatusCode.OK,Deleted);
}

_service是使用_db的数据库访问服务 - 我的项目的DbContext的一个实例,在服务类的构造函数中定义一次。



在我的客户端中,我使用for循环将一大堆异步AJAX调用发送到delete方法,尝试连续删除多个文件夹。那就是这样的东西:





,这样:





开始发生。我有一种感觉,这是由于种族条件,但我不知道如何去修复它,如果是这样的情况。我应该为每个电话创建一个新的dbcontext实例吗?如果是,应该在哪里创建?在repository.cs的每个方法中(为每个方法的使用创建单个dbContext)?



任何帮助将不胜感激。

解决方案

是的,每次调用需要单独的DbContext。从模式,如果EF的情况基本上意味着在一个类中包装你的 DbContext (你不希望它将EF特定的类暴露给你的业务类的DbContext),这样你就可以应用代码(或根据分层,业务代码)可以写出类似的东西;

  [HttpDelete ] 
public HttpResponseMessage DeleteFolder(int id)
{
using(var uow = new UnitOfWork()){//创建一个新的DbContext
_service.DeleteFolder(uow,id) ;
uow.Commit();
return Request.CreateResponse(HttpStatusCode.OK,Deleted);
} // Uncommitted UoW回滚Dispose
} //即未处理的异常。

...或者如果您认为通过UoW与每个服务/存储库方法是恼人的(我做),您可以让UnitOfWOrk构造函数将其保存为 HttpContext.Current.Items 中的当前活动工作单元,以便任何服务/存储库可以获取当前单位的工作。


In my WebAPI controller I have this:

   [HttpDelete]
    public HttpResponseMessage DeleteFolder(int id)
    {
        _service.DeleteFolder(id);
        return Request.CreateResponse(HttpStatusCode.OK, "Deleted");
    }

_service is a db access service using _db - an instance of my project's DbContext, defined once in the constructor of the service class.

In my client, I used a for loop to send a bunch of asynchronous AJAX calls to the delete method, attempting to delete multiple folders in succession. That's when stuff like this:

and this:

started happening. I have a feeling that it's due to race conditions but I'm not sure how to go about fixing it, if that's the case. Should I be creating a new instance of dbcontext for every call? If so, where should this be created? Within each method of repository.cs (where a single dbContext is created for every method's use)?

Any help would be much appreciated.

解决方案

Yes, you need a separate DbContext per call. From the docs;

What you could do (for example, depending on how you're using transactions) is to use the Unit of Work pattern, which if EF's case basically means wrapping your DbContext in a class (you don't want it exposing EF specific classes like DbContext to your business classes) so that you in your application code (or, depending on layering, business code) can write something like;

[HttpDelete]
public HttpResponseMessage DeleteFolder(int id)
{
    using(var uow = new UnitOfWork()) {  // Creates a new DbContext
        _service.DeleteFolder(uow, id);
        uow.Commit();          
        return Request.CreateResponse(HttpStatusCode.OK, "Deleted");
    }                                    // Uncommitted UoW rolls back on Dispose
}                                        // ie on unhandled exceptions.

...or if you think passing the UoW with every service/repository method is annoying (I do), you can let the UnitOfWOrk constructor save it as the "currently active Unit of Work" in HttpContext.Current.Items, so that any service/repository can fetch the current Unit of Work when needed.

这篇关于当我使用EF(和WebAPI)向我的数据文本发送高频请求时,出现奇怪的竞争条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 03:28