网络核心DbContextPool与AddDbContextPool等

时间:2018-12-01 05:10:19

标签: c# entity-framework .net-core entity-framework-core dbcontext

我正在尝试以高处理速率使用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,也将它们缓存。我仍然会配置选项以允许重试,但是同样,那些超时将是由于外部原因发生的,而不是因为我的代码正在创建数百个实例,所有实例都试图将微小的消息保存到数据库中。

1 个答案:

答案 0 :(得分:1)

  

我无法将范围设置为瞬态,找不到语法!   有一个吗?

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

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

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

  

如何解决这个问题?

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