While performing database operation, one major thing need to be taken care of isConcurrency 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,

image

From above diagram you can infer that, essentially there are three steps involved in concurrency conflict

Step 1

LINQ fetch data from database when database is in state "A"

Step 2

While LINQ is manipulating the data in DataContext , database has been modified by some other part and changed its state to "B"

Step 3

LINQ is trying to update the data in the database in state "B"

Now there are two ways LINQ can resolve this

  1. Override database changes
  2. 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

clip_image002

When you create entity class in LINQ to SQL, you can attribute a column with UpdateCheckas shown above. Any column attributed with UpdateCheck would be checked for optimistic concurrency.

UpdateCheck is an enum with three values.

clip_image003

As it is very readable that,

Never Column value would never be checked for detecting conflict
Always Column value would always be checked for conflict
WhenChanged 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

  1. Put the code updating in try catch block
  2. Check for ChangeConflictException
  3. In the catch block use RefreshMode to resolve conflict issue.

You can do concurrency check as follows ,

Modify SubmitChanges

You have submitchnages() overloaded and it takes ConflictMode enum as value

image

If you examine ConflictMode enum

clip_image001

It is having two values

image

Usually you use ConflictMode enum with submitchage as below,

clip_image005

Put SubmitChanges in try catch

After modifying SubmitChanges, on the conflict ChangeConflictException will be thrown by the LINQ .

image

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.

image

image

Consider a very simple update operation as below with breakpoint

image

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

image

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,

01 using System;
02 using System.Linq;
03 using System.Data.Linq;
04  
05 namespace Concurrency
06 {
07     class Program
08     {
09         static void Main(string[] args)
10         {
11  
12             DataClasses1DataContext context = new DataClasses1DataContext();
13  
14             #region without handling Conflict
15             //Person personToUpdate = (from r in context.Persons
16             //                         where r.PersonID == 1
17             //                         select r).FirstOrDefault();
18             //personToUpdate.FirstName = "John Papa";
19             //context.SubmitChanges();
20  
21             

Post a Comment

0 Comments