asp.net mvc 4 - Okay to share DbContext per thread?

后端 未结 2 777
礼貌的吻别
礼貌的吻别 2021-02-06 12:03

From One DbContext per web request... why?

My understanding is that a DbContext instance should not be shared across concurrent web request, so definitely not across thr

2条回答
  •  暖寄归人
    2021-02-06 12:41

    is it safe to dependency inject a DbContext instance for each thread?

    It depends. If your idea is to have one DbContext per web request, and the consistency of your application depends on it, having one DbContext per thread is a bad idea, since a single web request can still get multiple DbContext instances. And since ASP.NET pools threads, instances that are cached per thread, will live for the duration of the entire application, which is very bad for a DbContext (as explained here).

    On the other hand, you might be able to come up with a caching scheme that ensures that a single DbContext is used for a single web request, and is returned to a pool when the request is finished, so other web requests could pick it up. This is basically the way how connection pooling in .NET works. But since DbContext instances cache data, that data becomes stale very quickly, so even if you are able to come up with a thread-safe solution, your system still behaves in an inconsistent way, since at some seemingly random moments, old data is shown to the user, while in a following request new data is shown.

    I think it is possible to clear the DbContext's cache at the beginning of a web request, but that would be basically be the same as creating a new DbContext for that request, but with the downside of much slower performance.

    I'm just wondering if it is safe and sufficient to use PerThreadLifetimeManager.

    No, it isn't safe because of the reasons described above.

    But it is actually quite easy to register a DbContext on a per-web request basis:

    container.Register(new InjectionFactory(c => {
        var context = (MyApplicationEntities)HttpContext.Current.Items["__dbcontext"];
    
        if (context == null) {
            context = new MyApplicationEntities();
            HttpContext.Current.Items["__dbcontext"] = context;
        }
    
        return context;
    })); 
    

提交回复
热议问题