我正在尝试以高处理速率消耗Kafka队列并将结果使用.net core 2.1中的EF将结果存储在MySql中
我尝试同时使用AddDbContextAddDbContextPool,并且在两种情况下都遇到了问题。

1)当使用AddDbContext时,我成功的唯一方法是将其限定在transient范围内,这样,每次我需要调用数据插入时,您都会获得一个新的DataContext实例。我的队列很大,最终与mqSQL服务器的连接过多,因此最终我开始收到大量超时错误。

我知道我可以添加选项以重试瞬时错误(超时是其中之一),但是我最感兴趣的是如何将DataContext实例的数量减少到不会影响数据库的数量。这把我带到了下一个尝试

2)使用AddDbContextPool时,我无法将范围设置为transient找不到语法!有一个吗?无法为每个调用获取新实例,我会得到另一种奇怪的错误,这些错误通常可以通过短暂的生命周期来解决
An attempt was made to use the context while it is being configured.A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point.This can happen if a second operation is started on this context before a previous operation completed.Any instance members are not guaranteed to be thread safe.
同样,据我所知,AddDbContextPool中的poolsize参数只是为要重用的DbContext对象设置缓存大小,而决不妨碍连接总数。我希望池达到饱和时能够阻止下一个“get DBContext”调用,直到一个实例可用为止。

因此,我向社区提出的问题是如何解决这个问题?我希望将DbContext实例的数量减少到固定数量,例如10,也将它们缓存。我仍然会配置选项以允许重试,但是同样,这些超时将是由于外部原因而发生的,而不是因为我的代码正在创建数百个实例,而这些实例都试图将微小的消息保存到数据库中。

最佳答案



不,很明显,因为DbContext的生存期是由缓存控制的。

由于DbContext类不是线程安全的,因此从多个线程访问DbContext的相同实例,会导致收到错误消息。实际上,这意味着您的DbContext池无法正常工作,这可能是因为您在使用来自消息队列的消息时未创建作用域,因此DbContext实例在多个线程之间共享。此范围是在HTTP请求到达时在MVC的幕后创建的,但是在其他类型的应用程序中,您必须自己创建它。

请注意,DbContext池和连接池之间也有区别。如果需要控制应用程序的连接数,则应使用连接池。



我根本不涉及上下文池,相反,我宁愿设置某种限制机制来控制从您的队列消耗的多个线程。

10-01 19:34