.Net Core DbContextPool与AddDbContextPool的区别及更多相关信息

6
我正在尝试以高速处理消耗Kafka队列,并使用来自.NET Core 2.1的EF将结果存储在MySql中。我尝试过使用AddDbContextAddDbContextPool,但在两种情况下都遇到了问题。
1)当使用AddDbContext时,唯一成功的方法是将其范围设置为transient,这样每次需要调用数据插入时都会获得一个新的DataContext实例。我的队列很大,最终连接到mqSQL服务器的连接太多,因此我开始遇到大量超时错误。
我知道我可以添加选项以重试瞬态错误(超时就是其中之一),但我主要关心如何将DataContext实例的数量减少到不会打击数据库的数量。这使我尝试了下一个解决方案。
2)当使用AddDbContextPool时,我无法将范围设置为transient,找不到语法!有吗?不能在每次调用时获取新实例,我会遇到另一种奇怪的错误类型,通常可以通过短暂的生命周期解决。
“尝试在配置上下文时使用上下文。 由于此时仍在配置它,因此OnConfiguring内部无法使用DbContext实例。 如果在上一个操作完成之前启动了此上下文上的第二个操作,则可能会发生这种情况。 任何实例成员都不能保证是线程安全的。”
同时,据我所知,在AddDbContextPool中的poolsize参数仅设置缓存大小,以重复使用DbContext对象,并且绝不会防止总连接数。当池饱和时,我希望能够阻止下一个“get DBContext”调用,直到有一个实例可用。
因此,我的问题是如何解决这个问题?我希望将DataContext实例的数量减少到固定数量,例如10,并对它们进行缓存。我仍然会配置选项以允许重试,但再次说明,这些超时会出现由于外部原因而不是因为我的代码创建了数百个实例,所有这些实例都试图将微小的消息保存到数据库中。

你实际的问题是上下文实例被多个线程访问。你需要解决这个问题。 - Gert Arnold
1个回答

2
我无法将范围设置为瞬态,找不到语法!有吗?
没有,因为DbContext的生命周期由缓存控制。
您收到的错误消息是由于从多个线程访问同一实例的DbContext类导致的,因为DbContext类不是线程安全的。事实上,这意味着您的DbContext池不起作用,可能是因为在从消息队列中消耗消息时未创建范围,因此DbContext实例在多个线程之间共享。当HTTP请求到达时,在MVC中会在后台创建此范围,但在其他类型的应用程序中,您必须自己创建它。
请注意,DbContext池和连接池之间也有区别。如果您需要控制应用程序中的连接数,请使用连接池。
如何解决这个问题?
我根本不会涉及上下文池,而是会设置一些限流机制来控制从您的队列中消耗的线程数量。

1
谢谢。关于 DbContext 池,我错过了这个 当 HTTP 请求到达时,在 MVC 中会在后台创建此范围,但对于其他类型的应用程序,您必须自己创建它。是的,那还不足以消除超时,所以我需要控制“正在发送”消息的总数。谢谢。 - Dan M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接