How to: Handle Concurrency Conflicts
This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.
By default, Telerik Data Access implements an optimistic concurrency control. This means that locks are not held on data in the data store between the moment the data is queried and the moment the data is updated. Telerik Data Access checks for changes in the database before saving changes to the database. Any conflicts will cause a Telerik.OpenAccess.Exceptions.OptimisticVerificationException. The way you handle concurrency exceptions depends on the business rules required by your application. Telerik Data Access provides many resources for detecting and resolving conflicts that are a result from multi-user changes to the database.
Detecting Concurrency Conflicts During SaveChanges
The following example shows a try/catch statement that catches an OptimisticVerificationException.
using ( EntitiesModel dbContext = new EntitiesModel() )
{
Category categoryToUpdate = dbContext.Categories.FirstOrDefault();
categoryToUpdate.CategoryName = "NewName";
try
{
dbContext.SaveChanges();
}
catch (Telerik.OpenAccess.Exceptions.OptimisticVerificationException ex)
{
Console.WriteLine("Optimistic concurrency error.");
Console.WriteLine(ex.Message);
}
}
Using dbContext As New EntitiesModel()
Dim categoryToUpdate As Category = dbContext.Categories.FirstOrDefault()
categoryToUpdate.CategoryName = "NewName"
Try
dbContext.SaveChanges()
Catch ex As Telerik.OpenAccess.Exceptions.OptimisticVerificationException
Console.WriteLine("Optimistic concurrency error.")
Console.WriteLine(ex.Message)
End Try
End Using
The OpenAccessContext exposes a method named GetLastConflicts, which allows you to get the ObjectKeys for all failing object.
IList<ConcurrencyConflict> conflicts = dbContext.GetLastConflicts();
Dim conflicts As IList(Of ConcurrencyConflict) = dbContext.GetLastConflicts()
Resolving Concurrency Conflicts by Retaining Database Values
When making updates in such high concurrency scenarios, you could use the Refresh method frequently. After Refresh is called, the object’s original values will always be updated with the data source value, but the current values might or might not be updated with the data source value. This depends on the RefreshMode value, it controls how changes are propagated. The OverwriteChangesFromStore value means that the passed object should be updated to match the data source values. The PreserveChanges value means that the actual changes in the object will be kept but all clean data will be re-read.