I was warned not to use more than one DBEntityContext of the Entity Framework in my application. The reason being the risk of deadlock due to concurrent access to the database.
Can anybody confirm this? If this true is it a good idea to implement a Singleton object for the DBContext?
Any Articles on this issue are welcome.
Thank you Advance.
ObjectContext and DbContext are not thread safe. See http://msdn.microsoft.com/library/system.data.objects.objectcontext.aspx. If you use them in a multithreaded environment like ASP.NET, you are running in big trouble when using a single instance. It is recommended to use one ObjectContext per request. The ObjectContext has to be disposed at the end of the request. The Article Managing Entity Framework ObjectContext lifespan and scope in n-layered ASP.NET applications may be helpfull.
Is it possible, that you missunderstood your advisor who told you about deadlocks? May be he wants to warn you about possible deadlocks when using ObjectContext the wrong way.
In web application you have to use a new context instance per each processed web request and dispose the instance after you don't need it any more. Context and anything related to EF is not thread safe. Moreover it implement unit of work and identity map patterns which makes other restrictions on using the context instance.
Dead locks can happen but that is something you must solve by correct transaction design.
Related
I have a question guys, what would happen if I (using Entity Framework) call SaveChangesAsync() multiple times simultaneously? What would happen when more than one thread is trying to actually write data in the database at the same time? How is it handled? I'm working a project where I have to fetch-and-save periodically and I'm afraid that the time it takes to process each package of data in some cases might be bigger than the time-interval between calls. I'm new to Entity Framework and I find it fascinating, but I still have my doubts regarding the action behind the scenes. Any help will be much appreciated.
If "simultaneously" meand by multiple threads then you can't do that because EF is not thread safe.
Here are some examples that might help you.
https://github.com/mjrousos/MultiThreadedEFCoreSample
Reference here:
https://learn.microsoft.com/fr-fr/ef/core/miscellaneous/async
I am following Tom Dykstra's Getting Started with Entity Framework 6 Code First using MVC 5 tutorial. Part 4 of this tutorial covers EF6's connection resiliency and command interception features.
As a way of demonstrating the use of command interception, the tutorial provides two example DbCommandInterceptor implementations. One (SchoolInterceptorLogging) interfaces with a logger to record each SQL command that is executed, how much time it took to execute, and whether there was an exception. The other example (SchoolInterceptorTransientErrors) simulates transient DB errors so that connection resiliency can be tested.
Although the tutorial does not specifically mention the issue of synchronization, I assume that because a single instance of the DbCommandInterceptor is registered via DbInterception.Add(), that any per-DbContext state utilized by the DbCommandInterceptor must be synchronized. For example, SchoolInterceptorLogging should probably synchronize use of the _stopwatch, and SchoolInterceptorTransientErrors should probably synchronize the _counter.
I thought about using thread-local storage via ThreadStaticAttribute or ThreadLocal<T>. However, I am not sure that this is sufficient. Suppose that my application uses DbContext.SaveChangesAsync() to asynchronously save all changes. Isn't it possible for the same thread to handle two asynchronous save operations? If so, then thread-local storage wouldn't work.
Another idea is to store per-DbContext state in the call context. However, when using the CallContext, it is recommended that only immutable types should be used. (See Stephen Cleary's blog post, Implicit Async Context ("AsyncLocal").)
A third idea is to use a ConcurrentDictionary where the keys are the DbCommandInterceptionContext object passed to NonQueryExecuting()/NonQueryExecuted(), ReaderExecuting()/ReaderExecuted(), or ScalarExecuting()/ScalarExecuted(), and the values are a state object. However, I have two questions about this approach:
Is the DbCommandInterceptionContext object that is passed to the *Executing()/*Executed() method distinct for each save operation?
From setting a breakpoint in ReaderExecuting() and calling GetHashCode() on the interception context object, it appears to be distinct for each retry let alone save operation (tested EntityFramework version 6.1.3).
Will the *Executed() method always be called?
This is to make sure that anything added to the ConcurrentDictionary in the *Executing() method can always be cleaned up by the *Executed() method.
So, how should a DbCommandInterceptor with per-DbContext state be implemented?
My DBA says that there are way too many connection open and he thinks it is my code in .net that is leaving them open.
I am using LINQ querys and EF code first.
Example Method:
public List<Stuff> GetStuff()
{
var db = new DBContext();
var results = db.stuff.toList();
return results;
}
Do I need to dispose the db var once I am done? My understanding is that I didn't need to in EF and LINQ. Please point me to a Microsoft documentation about managing connection in code or best practices for LINQ/EF and db connections
Update:
I added
db.Connection.Close();
db.Dispose();
and I still see the open connection in SQL after the two lines were executed. Is there a reason why it wouldn't close when I force it to close?
You should listen to your DBA! Yes, use a using. Do not leave connections open unnecessarily. You should connect, do your business with the db, and close that connection, freeing it up for another process. This is especially true in high volume systems.
Edit. Let me further explain with my own experiences here. In low volume processing, it probably isn't an issue, but it's a bad habit not to dispose of something explicitly or not-wrap it in a using when it clearly implements IDisposable.
In high-volume situations, this is just asking for disaster. Sql server will allot so many connections per application (can be specified in the connection string). What happens is processes will spend time waiting for connections to free up if they're not promptly closed. This generally leads to timeouts or deadlocks in some situations.
Sure, you can tweak Sql server connection mgmt and such, but everytime you tweak a setting, you're making a compromise. You must consider backups running, other jobs running, etc. This is why a wise developer will listen to their DBA's warnings. It's not always all about the code...
I just asked this same question over on Programmers.SE. Robert Harvey gave a great answer.
In general, you don't need to use Using statements with Entity Framework data contexts. Lazy collections is one of the reasons why.
I encourage you to read the entire answer on Programmers.SE as well as the links Robert provides in the answer.
The entity framework uses, as far as i know, connection pooling by default to reduce the overhead of creating new connections everytime.
Are the connections closed when you close your application?
If so, you could try to decrease the Max Pool Size in your connection string or disable connection pooling entirely.
See here for a reference of possible options in your connection string.
By default DbContext automatically manages the connection for you. So you shouldn't have to explicitly call Dispose.
Blog post on the subject: Link
But I believe not disposing can cause performance issues if you're processing a lot of requests. You should add a using statement to see whether or not it's causing a problem in your case.
Yes, if your method defines a Unit of Work; no, if something more primitive. (P.S. something somewhere in your code should define a Unit of Work, and that thing should be wrapped in a using (var context = new DbContext()) {} or equivalent.)
And if you belong to the school of thought that your DbContext is your Unit of Work, then you'll always be wrapping that bad boy with a using block: the local caching of data previously fetched during the context lifetime together with the SaveChanges method act as a sort of lightweight transaction, and your Dispose (without calling SaveChanges) is your Rollback (whereas your SaveChanges is your Commit).
Check this out, here's a standard protocol on how to use IDisposable objects.
https://msdn.microsoft.com/en-us/library/yh598w02.aspx
It says:
"As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement."
As they have access to unmanaged resources, you should always consider a "using" statement.
I have a few long running tasks on my server. Basically they are like scheduled tasks - they run from time to time.
They all required access to the DB and I use Entity Framework for that. Each task uses a DbContext for access.
Should the DbContext object be recreated on every run or should I reuse it?
I should say "it depends" as there are probably scenarios where both answers are valid, however the most reasonable answer is "the context should be disposed as soon as it is not needed" which in practice means "dispose rather sooner than later".
The risk that comes from such answer is that newcomers sometimes conclude that the context should be disposed as otfen as possible which sometimes lead to a code I review where there are consecutive "usings" that create a context, use it for one or two operations, dispose and then another context comes up next line. This is of course not recommended also.
In case of web apps, the natural lifecycle is connected with a lifecycle of web requests. In case of system services / other long running applications one of lifecycle strategies is "per business process instance" / "per usecase instance" where business processing / use case implementations define natural borders where separate instances of contexts make sense.
Yes, DbContext should only live for a very short time. It is effectively your unit of work
You should definitely create it each time you're going to use it. (Well, you should inject it but that's another discussion :-))
Update : OK, I accept that 'create it each time you're going to use it' could be misleading. I'm so used to context being an instance on a class that is injected and so lives only for the life of a request that I struggle to think of it any other way... #wiktor's answer is definitely better as it more correctly expresses the idea that you should "dispose sooner rather than later"
When using ObjectContext in EF 5, should it be a singleton or is it better to create new instance every time like SqlConnection. If so, why?
Create and dispose the context as soon as possible. Quote from the guidelines on MSDN:
Here are some general guidelines when deciding on the lifetime of the
context:
When working with long-running context consider the following:
As you load more objects and their references into memory, the memory
consumption of the context may increase rapidly. This may cause performance issues.
Remember to dispose of the context when it is no
longer required.
If an exception causes the context to be in an
unrecoverable state, the whole application may terminate. The chances
of running into concurrency-related issues increase as the gap between
the time when the data is queried and updated grows.
When working with Web applications, use a context instance per request.
When working with Windows Presentation Foundation (WPF) or Windows Forms, use a
context instance per form. This lets you use change-tracking
functionality that context provides.