首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ef核中的DbContext和DbcontextPool

ef核中的DbContext和DbcontextPool
EN

Stack Overflow用户
提问于 2022-04-11 09:46:47
回答 1查看 1.5K关注 0票数 1

我在Efcore中阅读了很多关于DBcontext及其生命周期的文档和文章,但是,我有一些问题。

基于这个链接"https://learn.microsoft.com/en-us/ef/core/dbcontext-configuration/“,DBcontext的最佳生存期和AddDbContext的默认生存期是scope,但在本文档的以下两句话中存在矛盾。

"DbContext不是线程安全的。不要在线程之间共享上下文。在继续使用上下文实例之前,一定要等待所有异步调用。“

另一方面,也有人提到,

“在大多数核心应用程序中,安全地避免并发访问问题,因为在给定的时间只有一个线程执行每个客户端请求,而且因为每个请求都有一个单独的依赖项注入作用域(因此也是一个单独的DbContext实例)。”

  1. 我对将DBcontext注册为作用域服务是否是线程安全感到困惑?
  2. 详细地将DBcontext注册为单例服务有哪些问题?

此外,我还阅读了一些禁止注册singleton DbContext的文档,但是AddDbContextPool进行了单例DBcontext的注册。所以有一些关于Dbcontextpool的问题。

  1. 使用DbContextPool而不是DbContext有什么影响?
  2. 什么时候我们应该使用它,当我们使用contextPool时应该考虑什么?
  3. DbContextPool是线程安全吗?
  4. 是否因为在应用程序的整个生命周期中存储了许多dbset实例而导致内存问题?
  5. 更改跟踪或ef的任何部分是否在DB上下文池中失败?

每个网络请求一个DbContext ..。为什么?

.NET实体框架与事务

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-11 12:34:00

我理解您为什么认为Microsoft文档中的语言令人困惑。我会帮你解开的:

  • "DbContext不是线程安全的。“这个语句意味着从多个线程并行访问DbContext是不安全的。堆栈溢出回答您已经引用过的问题,请解释这一点。
  • “不要在线程之间共享上下文。”这条语句令人困惑,因为异步(异步/等待)操作倾向于跨多个线程运行,尽管从未并行运行。更简单的说法是:“不要在web请求之间共享上下文”,因为单个web请求通常运行单个工作单元,尽管它可能异步运行代码,但通常不会并行运行代码。
  • “在大多数ASP.NET核心应用程序中,DbContext是安全的,不受并发访问问题的影响”:本文有点误导读者,因为它可能让读者相信DbContext实例是线程安全的,但它们并不安全。作者在这里要说的是,使用默认配置(即使用AddDbContext<T>(),ASP.NET核心确保每个请求都有自己的DbContext实例,因此默认情况下使其“不受并发访问的影响”)。

1我对将DBcontext注册为作用域服务是否是线程安全感到困惑?

DbContext实例本身并不是线程安全的,这就是为什么您应该将它们注册为Scoped,因为这将防止从多个请求访问它们,从而使它们的使用线程安全。

2详细地将DBcontext注册为单例服务有哪些问题?

这个答案中已经详细描述了这一点,您已经引用了这些内容。我想这个答案有很多细节,我不想在这里重复。

此外,我还阅读了一些禁止注册单例DbContext的文档,然而,AddDbContextPool制作了注册单例DBcontext。所以有一些关于Dbcontextpool的问题。

DbContext池特性与将DbContext注册为单例非常不同,因为:

  • 池机制确保并行请求获得自己的DbContext实例。
  • 因此,在使用单例生活方式时,多个DbContext实例存在于池中,而整个应用程序只存在一个实例。
  • 因此,使用单例生活方式可以确保单个实例被重用,这将导致部署(再次) 这里的无数问题。
  • 池机制确保在DI作用域结束时,“清理”DbContext并将其带回池,这样新的请求就可以重用它。

使用DbContextPool而不是DbContext有什么影响?

有关这方面的更多信息,请在文档中提供。

什么时候我们应该使用它,当我们使用contextPool时应该考虑什么?

当您的应用程序需要它带来的性能好处时。在决定添加之前,您可能需要对其进行基准测试。

DbContextPool是线程安全吗?

是的,就像注册一个DbContext是线程安全的Scoped一样;如果您意外地将一个DbContext实例保存在一个可重用的交叉请求对象中,这个保证就被破坏了。您必须很好地照顾Scoped对象,以防止它们成为俘虏属地

是否因为在应用程序的整个生命周期中存储了许多dbset实例而导致内存问题?

记忆的损失是很难被察觉的。对于在请求结束后被带回池的每个DbContext,都会清除所谓的第一级缓存。这是为了防止DbContext变得陈旧,并防止内存问题。

更改跟踪或ef的任何部分是否在DB上下文池中失败?

不,它没有。在大多数情况下,使您的DbContext池只需要基础设施更改(更改应用程序的启动路径),并且对应用程序的其他部分是透明的。但是,请务必阅读,以熟悉使用DbContext池的后果。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71825752

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档