Resolving Concurrency conflicts in LINQ

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,

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 UpdateCheck as 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,


using System;
using System.Linq;
using System.Data.Linq;

namespace Concurrency
{
    class Program
    {
        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";
            //context.SubmitChanges();

            #endregion

            #region hanlding conflict

            try
            {
                Person personToUpdateConflict = (from r in context.Persons
                                                 where r.PersonID == 1
                                                 select r).FirstOrDefault();
                personToUpdateConflict.FirstName = "JohnPapa";
                context.SubmitChanges(ConflictMode.FailOnFirstConflict);

            }
            catch (ChangeConflictException c)
            {
                foreach (ObjectChangeConflict o in context.ChangeConflicts)
                {
                    o.Resolve(RefreshMode.KeepChanges);

                }
                context.SubmitChanges();

            }

            #endregion
            Console.ReadKey(true);
        }
    }
}

Now you know how to resolve conflict in LINQ. I hope this post was useful. Thanks for reading  Smile

Add to FacebookAdd to DiggAdd to Del.icio.usAdd to StumbleuponAdd to RedditAdd to BlinklistAdd to TwitterAdd to TechnoratiAdd to Yahoo BuzzAdd to Newsvine

7 thoughts on “Resolving Concurrency conflicts in LINQ

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s