我正在尝试以高处理速率使用Kafka队列,并使用.net core 2.1中的EF将结果存储在MySql中
我尝试同时使用AddDbContext
和AddDbContextPool
,但在两种情况下都遇到了问题。
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,也将它们缓存。我仍然会配置选项以允许重试,但是同样,那些超时将是由于外部原因发生的,而不是因为我的代码正在创建数百个实例,所有实例都试图将微小的消息保存到数据库中。
答案 0 :(得分:1)
我无法将范围设置为瞬态,找不到语法! 有一个吗?
不,显然是因为DbContext的生存期由缓存控制。
您收到的错误消息是由于从多个线程访问DbContext的相同实例引起的,因为DbContext类不是线程安全的。实际上,这意味着您的DbContext池无法正常工作,可能是因为您在使用来自消息队列的消息时未创建作用域,因此DbContext实例在多个线程之间共享。此范围是在HTTP请求到达时在MVC的幕后创建的,但是在其他类型的应用程序中,您必须自己创建它。
请注意,DbContext池和连接池之间也有区别。如果需要控制应用程序的连接数,则应使用连接池。
如何解决这个问题?
我根本不涉及上下文池,相反,我宁愿设置某种限制机制来控制从您的队列消耗的大量线程。