-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ModelBuilder being thread safe? #15243
Comments
I did ask the question also on SO: https://stackoverflow.com/q/55488880/8504288 |
@hkoestin Since EnsureCreated is manipulating the database schema, it must not be called concurrently from multiple threads. Even if we did allow two threads to call into it concurrently, this would only work if one of the threads blocks, which is what you are already seeing for model creation. Continuing with the model, it is built once and cached because generally building the model can be slow. By default, models are cached based on the DbContext type, but this can be configured. So you could build two models in parallel if you wanted to. In general this is unlikely to be good for perf. |
@ajcvickers thank you for your feedback. I see, that there is no point in seeking for a performance boost in this topic. Will just call the ensure created once. I see, that model building is quite costly and that is the reason why EF tries to cache it etc. However, the models which needs to be built are very specific to the DbContext, namely only the registered entities in that very DbContext. Why isn't there a mechanism in place, which sort of isolates the models per db-context type? Then, model building (also for huge mappings with tons of entities etc.) can happen on a very small and limited subset (each DbContext). The database facade would need to have a cache in place, which of the models for which DbContext were already build etc. I tried something different now: one DbContext pointing to SQLite, one pointing to SQL Server. There, building works in parallel. At least, out of maybe 20 runs, I did not see an issue. |
Hello,
This here is not really an issue but more of a question, but since I have not found anything helping on the internet and the mighty search engine of your choice, I wanted to ask that in here.
I know, that per design, EF Core was not meant to be thread safe. I totally get that point of isolation for the DbContext instances, but I was wondering, why also the model building already seems to be impacted by that.
Background
In order to speed up start-up time for an application, I wanted to do 2 queries in parallel, using 2 distinct DbContexts. Basically, each of them reflects a "Bounded Context Database" in my domain, one mapping to environment settings (user settings, stored UI layouts, ...) in the database and one mapping to system settings (system passwords, ...).
So when I fire up the application, I wanted to start two tasks, one going to the environment settings to fetch already the layout stuff and user settings, and one going to the system settings, to check on correct passwords etc.
Problem
Both tasks would create the underlying DbContext on their own, so the DbContext is created at that thread. But somehow, it seems, that the actual model-building under the hood of EF Core is done differently or not "per" thread or "per DbContext".
When I execute my application, from time to time it crashes with the following error:
Having a look at my logs however reveals, that the entity was registered at the context previously.
Afterwards, thread 16 (getting the system culture from the EvaluationSettings entity) fails.
When I do debug that issue and try to get the insights of the model-builder, I see, that only the Evaluation type is known to the DbContext model builder. The rest somehow is gone.
Question
Could it be, that because 3 threads are calling "EnsureCreated" in parallel, only those entities get a model in the context, which were registered at that point of time?
It seems, that on that level, there is no isolation of "this model belongs to that context", right?
Anybody has a possible solution to that?
Or a suggestion how to solve that?
Version
EF Core 2.2.1
The text was updated successfully, but these errors were encountered: