While performing database operation, one major thing need to be taken care of is Concurrency Conflicts. Concurrency conflict can happen when two sources are try to modify database at the same time.
Let us understand conflict in LINQ with an example,
From above diagram you can infer that, essentially there are three steps involved in concurrency conflict
LINQ fetch data from database when database is in state “A”
While LINQ is manipulating the data in DataContext , database has been modified by some other part and changed its state to “B”
LINQ is trying to update the data in the database in state “B”
Now there are two ways LINQ can resolve this
- Override database changes
- Ignore changes made by LINQ itself.
By default, LINQ DataContext supports optimistic concurrency.
Very first to resolve concurrency conflict, you need to find table columns involved in conflict. You can put a check flag on entity column
When you create entity class in LINQ to SQL, you can attribute a column with UpdateCheck as shown above. Any column attributed with UpdateCheck would be checked for optimistic concurrency.
UpdateCheck is an enum with three values.
As it is very readable that,
||Column value would never be checked for detecting conflict
||Column value would always be checked for conflict
||Column value would only be checked for conflict when value of column is changed.
If you attribute all the columns for update check then obviously performance would be degraded.
Other option you have is as follows
- Put the code updating in try catch block
- Check for ChangeConflictException
- In the catch block use RefreshMode to resolve conflict issue.
You can do concurrency check as follows ,
You have submitchnages() overloaded and it takes ConflictMode enum as value
If you examine ConflictMode enum
It is having two values
Usually you use ConflictMode enum with submitchage as below,
Put SubmitChanges in try catch
After modifying SubmitChanges, on the conflict ChangeConflictException will be thrown by the LINQ .
Handle the conflict in Exception
In the Exception block you need to handle that how you are going to resolve the conflict.
RefreshMode enumeration helps you to decide how to handle conflict. This got three values to resolve the conflict.
Consider a very simple update operation as below with breakpoint
Run the code and when code hit breakpoint at that point of time go back to database and change value of FirstName for PersonID =1
After changes made in database then come back to code and run from the breakpoint. You will very likely encounter with below exception at submitChanges() method call
Essentially what we did that we take the data in DataContext and then modified the value from other source and we got the concurrency conflict.
If we put all the discussion together we can handle conflict as below,
static void Main(string args)
DataClasses1DataContext context = new DataClasses1DataContext();
#region without handling Conflict
//Person personToUpdate = (from r in context.Persons
// where r.PersonID == 1
// select r).FirstOrDefault();
//personToUpdate.FirstName = "John Papa";
#region hanlding conflict
Person personToUpdateConflict = (from r in context.Persons
where r.PersonID == 1
personToUpdateConflict.FirstName = "JohnPapa";
catch (ChangeConflictException c)
foreach (ObjectChangeConflict o in context.ChangeConflicts)
Now you know how to resolve conflict in LINQ. I hope this post was useful. Thanks for reading