Explore ways to handle concurrency conflicts to maintain data integrity and data consistency when working with Entity Framework Concurrency handling can be used to maintain data integrity and data consistency when multiple users access the same resource concurrently. Concurrency violations can occur when you have interdependent transactions, i.e. transactions that are dependent on one another and try to access the same resource. Handling concurrency conflicts in Entity Framework Let’s now understand how each of these strategies work in Entity Framework. In the pessimistic concurrency, when a particular record is being updated, all other concurrent updates on the same record will be put on hold until the current operation is complete and the control is relinquished back so that other concurrent operations can continue. In the optimistic concurrency mode, the last saved record, “wins.” In this mode, it’s assumed that resource conflicts due to concurrent accesses to a shared resource are unlikely, but, not impossible. Incidentally, Entity Framework provides support for optimistic concurrency by default. Entity Framework doesn’t provide support for pessimistic concurrency out of the box. Let’s now understand how Entity Framework resolves concurrency conflicts when working in the optimistic concurrency (default mode). When working with optimistic concurrency handling mode, you would typically want to save data to your database assuming that the data hasn’t changed since it was loaded in the memory. Note that when your attempt to save changes to the database using the SaveChanges method on your data context instance, a DbUpdateConcurrencyException will be thrown. Let’s now understand how we can fix this. To check for concurrency violation you can include a field in your entity class and mark it using Timestamp attribute. Refer to the entity class given below. public class Author { public Int32 Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Address { get; set; } [Timestamp] public byte[] RowVersion { get; set; } } Now, Entity Framework supports two concurrency modes: None and Fixed. While the former implies that no concurrency checks would be performed when updating the entity, the latter implies that the original value of the property will be considered while executing WHERE clauses at the time when updates or deletes of data are done. If you have a property that is marked using Timestamp, the concurrency mode is considered as Fixed which in turn implies that the original value of the property would be considered in the WHERE clause of any updates or deletes of data for that particular entity. To resolve optimistic concurrency conflicts, you can take advantage of the Reload method to update the current values in your entity residing in the memory with the recent values in the database. Once reloaded with the updated data, you can attempt to persist your entity again in the database. The following code snippet illustrates how this can be achieved. using (var dbContext = new IDBDataContext()) { Author author = dbContext.Authors.Find(12); author.Address = "Hyderabad, Telengana, INDIA"; try { dbContext.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { ex.Entries.Single().Reload(); dbContext.SaveChanges(); } } Note that you can leverage the Entries method on the DbUpdateConcurrencyException instance to retrieve the list of DbEntityEntry instances corresponding to the entities that could not be updated when a SaveChanges method was called to persist the entities to the database. Now, the approach we just discussed is often called “stored wins” or “database wins” since the data contained in the entity is overwritten by the data available in the database. You can also follow another approach called “client wins”. In this strategy, the data from the database is retrieved to populate the entity. In essence, the data retrieved from the underlying database is set as the original values for the entity. The following code snippet illustrates how this can be achieved. try { dbContext.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { var data = ex.Entries.Single(); data.OriginalValues.SetValues(data.GetDatabaseValues()); } You can also check if the entity you are trying to update is already deleted by another user or, has already been updated by another user. The following code snippet illustrates how you can do this. catch (DbUpdateConcurrencyException ex) { var entity = ex.Entries.Single().GetDatabaseValues(); if (entity == null) { Console.WriteLine("The entity being updated is already deleted by another user..."); } else { Console.WriteLine("The entity being updated has already been updated by another user..."); } } If your database table doesn’t have a timestamp column or rowversion, you can take advantage of the ConcurrencyCheck attribute to detect concurrency conflicts when using Entity Framework. Here’s how this property is used. [Table("Authors"] public class Author { public Author() {} [Key] public int Id { get; set; } [ConcurrencyCheck] public string FirstName { get; set; } public string LastName { get; set; } public string Address { get; set; } } In doing do, SQL Server would automatically include AuthorName when executing update or delete statements in the database. Related content feature What is Rust? Safe, fast, and easy software development Unlike most programming languages, Rust doesn't make you choose between speed, safety, and ease of use. Find out how Rust delivers better code with fewer compromises, and a few downsides to consider before learning Rust. By Serdar Yegulalp Nov 20, 2024 11 mins Rust Programming Languages Software Development how-to Kotlin for Java developers: Classes and coroutines Kotlin was designed to bring more flexibility and flow to programming in the JVM. Here's an in-depth look at how Kotlin makes working with classes and objects easier and introduces coroutines to modernize concurrency. By Matthew Tyson Nov 20, 2024 9 mins Java Kotlin Programming Languages analysis Azure AI Foundry tools for changes in AI applications Microsoft’s launch of Azure AI Foundry at Ignite 2024 signals a welcome shift from chatbots to agents and to using AI for business process automation. By Simon Bisson Nov 20, 2024 7 mins Microsoft Azure Generative AI Development Tools news Microsoft unveils imaging APIs for Windows Copilot Runtime Generative AI-backed APIs will allow developers to build image super resolution, image segmentation, object erase, and OCR capabilities into Windows applications. By Paul Krill Nov 19, 2024 2 mins Generative AI APIs Development Libraries and Frameworks Resources Videos