Modifying Entity Framework entity from multiple threads

I have a UI thread that allows the user to set certain properties of an object.

I also have work threads that will automatically change the properties of an object, which is important that the user does not have access.

Is it possible to have different DbContexts

for each thread and just depend on my programming to always avoid modifying the same property and then try SaveChanges()

in a context that has the same object that has been modified differently?

Or is there a safer way to do this, that is, a way that a programmer might someday change the code so that the same property is modified from two different contexts safely? Or is the latter situation just one where the programmer has to be careful / refactoring?

+3


source to share


1 answer


Theoretical part

There are three ways to solve concurrency problems in a multi-threaded environment:

  • pessimistic , this can be easily done with the help locks

    for the editable item - nobody can edit the edited item. It is very difficult to implement, and this way is rather poor from performance view - all editing threads wait for one writer and just waste system resources.
  • optimistic , this is the default way of solving problems. The basic idea is that you continue the operation until you are successful. There is a lot of algorithm already presented, I recommend you read the whole wiki article and maybe some additional links and / or books on the topic.
  • semi-optimistic , this is a hybrid approach, this method is used if you need lock

    some operations, but not all.

Practical part

The authors of the Entity framework recommend using an optimistic approach in your application. A simple use case is to add a property RowVersion

or similar name to your model and catch it DBUpdatedException

in time UPDATE

.

You can use a solution Code-First

like:

[Timestamp]
public byte[] RowVersion { get; set; }

      

or Database-First

(add a column with the database editor):



enter image description here

After that, your code for a simple case will look like this:

using (var context = new SchoolDBEntities())
{
    try
    {
        context.Entry(student1WithUser2).State = EntityState.Modified;
        context.SaveChanges();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        Console.WriteLine("Optimistic Concurrency exception occured");
    }
}

      

As I understand it, you need to learn some of the properties of your data source, so I suggest you read a great article on such use cases (this is an MVC application, but I'm sure you can handle the basic idea).

You can also find several articles on concurrency in Entity Framework on MSDN:

  • Optimistic concurrency templates
    • Resolving optimistic concurrency exceptions with reloading (database win)
    • Resolving optimistic concurrency exceptions when client wins
    • Custom resolution of optimistic concurrency exceptions
    • Custom resolution of optimistic concurrency exceptions using objects
  • Working with property values
    • Getting and setting the current or initial value of an individual property
    • Getting and setting the current value of an untagged property
    • Checking if a property is marked as modified
    • Marking a property as changed
    • Reading current, original and database values ​​for all object properties
    • Setting current or original values ​​from another object
    • Setting current or original values ​​from a dictionary
    • Setting current or original values ​​from a dictionary using a property
    • Create a cloned object containing current, original, or database values
    • Getting and Setting the Current or Initial Values ​​of Complex Properties
    • Usage DbPropertyValues

      to access complex properties

As you can see, this situation is completely up to the developer, and you have a large number of templates that you can decide on your own.

+2


source







All Articles