Multiple simultaneous SaveChangesAsync() with EntityFramework - c#

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

Related

A write transaction is already opened by this thread in RavenDB4

I am attempting to update RavenDB storage for hangfire to RavenDB4 and I sometimes receive the following exception:
Raven.Client.Exceptions.RavenException: 'System.InvalidOperationException: A write transaction is already opened by this thread
I checked for unclosed session, but all session but one use using and the last one is specific because it is part of a class that acts like a transaction builder and is disposed on commit. I was unable to find what operations might take longer in the background or what could cause it.
I'd appreciate a little help with narrowing down what could cause this, because I have absolutely no idea and documentation didn't help much.
After upgrading to nightly version of RavenDB4 instead of RavenDB 4.0.0-rc-40025 (after Ayende Rahien suggested it should be a server issue) I never got this exception. I scheduling thousands of jobs before posting this as an answer to make sure it was server side issue.
Before the upgrade I got the exception pretty much every time I scheduled many jobs.

ASP.NET MVC multiple threads access database simultaneously

I am building a ASP.NET MVC 4 app using Entity Framework where multiple threads can access a table at the same time (add, delete row, etc.) Right now I am doing using (UserDBContext db = new UserDBContext()) within each controller (so a new DBContext is created for each request since MVC framework creates a seperate thread for each request). From what i read, this is safe; however, I am curious about:
What happens when two threads access the same table, but not the same row? Are both threads allowed to access simultaneously?
What happens when two threads modify the same row? say, one tries to read while the other tries to delete? Is one thread blocked (put to sleep), then gets waken up automatically when the other is done?
Thanks!
1: Locking in the database. Guaranteeing multi user scenarios is one of the top priority of databases. Learn the basics. There are good books.
2: Locking. Again. One will have to wait.
This is extremely fundamental so I would suggest you take 2 steps back and get something like "SQL for dummies" and learn about ACID conditions that any decent database guarantees. NOTHING in here has to do with EF by the way. This is all done on the database internal level.

How to remove entities from context concurrently?

Assume we have a List of entities to be removed:
var items = this.itemRepository.GetRange(1, 1000).ToList();
Instead of simple loop to delete items, I want to remove them concurrently like this:
items.AsParallel().ForAll(item =>
{
this.itemRepository.Remove(item);
});
this.UnitOfWork.Commit();
How do you suggest me to perform delete like this?
The EF context is not thread safe, so I wouldn't do this.
If you need performance then parallel != faster. Parallel code allows you to do more at the same time, but you tend to find that a single unit of work takes at least the same amount of time, but sometimes longer due to context switching etc, it's just that instead of doing 5 things one at a time, you are doing 5 things 5 at a time. This gets you more effective use of available hardware, and is less about performance and more about scalability and responsiveness.
As of EF 6 it exposes an asynchronous API for async/await support, but this again only allows one "concurrent" action against it. If you want to do multiple asynchronous reads, you will need one context per read action - this then simply puts the onus on the database to manage integrity.
EF6 added a RemoveRange method to the DbSet
This is more efficient than removing a single object at a time because by default Entity Framework calls DetectChanges in the Remove method whereas RemoveRange calls it just once.
However, when you call SaveChanges EF still executes individual delete statements. There is a proposal to Batch CUD in a future version.
References:
Entity Framework 6: The Ninja Edition
RemoveRange - implemented in EF6. (with a bug fixed in 6.1)
Upgrade to EF6 if you are not already using it, then you can do the following:
this.itemRepository.RemoveRange(items);

Writing synchronous queries or async ones

I am having an Asp.Net webforms page. I have 8 queries on the page on one of the complex page in the app. 2 queries can be cached and they are already cached but the other 6 requires hitting the DB. The page loads fine without any delay within 2 seconds. However, as a best practice along with performance I want to know if I should make them async. Problem is if I make them async, different connections have to be used for each query because currently I am storing the connection object in HttpContext.Current.Items and this won't be available if I am on different thread.
Should I be using Task api or should I leave them synchronous only? Please suggest best practice.
In my opinion the best option is to combine that queries together. If this is completely not possible run them using at least on sql connection. Using async probably will not increase time until you use shared sql connection but I am think it is not possible.
If you want to work on optimizing database access time then try to implement what Garath and mesterak suggested – that should give you additional performance improvements.
However, I must say that if my page was loading under 2s I wouldn’t really bother making any optimizations in this area.
Couple questions to ask yourself before you continue working on this:
How do you know if its database calls that are making the biggest impact on page load?
Have you seen the page trace or just assumed that it’s the database that’s making the biggest impact?
What have you done to optimize other elements?
Here are couple other suggestions for you to try:
Create page trace and examine the results. Here is a good tutorial on this.
Examine your page using PageSpeed and see if there are any optimizations in other areas
Check out these tutorials on how to optimize other page elements
I believe it depends on how you are making calls to your DB. It is possible to create a simple database handling class (static) that establishes one connection and then any queries performed can reuse the same connection object. Async calls just means you are performing them in parallel; this may improve user experience (faster performance), but the number of calls to the DB are the same. Perhaps we could better answer your question if you provide further details on how you are executing queries against your database in your code.

Entity Framework and DBContext Issues

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.

Categories

Resources