Weird race conditions when I send high-frequency requests to my datacontext using EF (and WebAPI)

我是研究僧i 提交于 2019-12-12 20:32:36

问题


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.


回答1:


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

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

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.



来源:https://stackoverflow.com/questions/17509498/weird-race-conditions-when-i-send-high-frequency-requests-to-my-datacontext-usin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!