EF CodeFirst (3) Concurrent processing, efcodefirst

Source: Internet
Author: User

EF CodeFirst (3) Concurrent processing, efcodefirst
There are two types of concurrency: Pessimistic concurrency and optimistic concurrency. Name ting Literature and Art

Pessimistic concurrencyWhat is pessimistic concurrency? Take the code that we often use as stupid control. There is A document. both A and B need to obtain and modify this document. If A occupies this document separately when reading the data of this document, B cannot obtain it, only when A reads the modification and releases the lock can B obtain the file, that is, the control of A person, others can only wait. This is the pessimistic lock. Due to worries, the data disorder caused by simultaneous operations by multiple people is probably because it is based on this mentality and named "pessimistic lock. Pessimistic locks are usually used in a highly competitive environment where frequent data competition occurs, and when the cost required to protect data through locks is less than the cost of rollback transactions. Optimistic ConcurrencyOptimistic Concurrency obviously, "psychologically" is the opposite, that is, "I don't worry about A and B getting control at the same time. A and B can read and modify at the same time, but after A is modified and saved, b. Modify and save the changes. At this time, the system will find that the current document is different from B's access to the system, and an error will be reported. This is obviously a good way to handle it. The optimistic lock application scenario is generally because the data competition is not particularly fierce, and the occasional data dispute requires a rollback transaction cost less than the cost required to lock the data when reading the data. The original intention of Optimistic Concurrency is that we do not want to see frequent data disputes. Pessimistic concurrency, if the locking cost is high, will significantly reduce the efficiency and reduce the concurrency of the system. Optimistic Concurrency is generally divided into three phases: Read phase-validation phase-write phase in the read phase, A and B read data into their respective machine buffer, at this time there is no validation, in the validation phase, system transactions perform synchronization validation on the files. If no problem occurs, the data is written to the third stage, and the data is finally submitted. Otherwise, an error is reported. Another common problem with the pessimistic lock is the "deadlock". For example, T1. T1. T1. but T1. T1, the lock will be stuck here until one Party cancels the lock first. Let's take a look at the scenarios that do not control concurrency.
// User user = new User {UserName = "shenwei", certID = "11111"}; using (BlogContext ctx = new BlogContext () {ctx. users. add (user); ctx. saveChanges () ;}/// insert a piece of data first and submit // define two contexts to operate BlogContext firContext = new BlogContext (); User u1 = firContext. users. firstOrDefault (); BlogContext secContext = new BlogContext (); User u2 = secContext. users. firstOrDefault (); u2.UserName = "zhangxiaomao"; // change the name and submit secContext. saveChanges (); u1.UserName = "xxxxxx"; u1.certID = "22222"; // another operation changes certid and also submits firContext. saveChanges ();
Database Query select * from Users; back to our EF codefirst. EntityFramework only supports optimistic concurrency, that is, EF does not want to see frequent data conflicts. Concurrency for the entire recordThe TimeStamp label must be used to implement Concurrency Control for EF, and only one label can be provided for a class, which must be of the byte [] type.
Public class Blog {public string ID {get; set;} public string BlogName {get; set;} public string BlogAuthor {get; set ;} public virtual List <Post> Posts {get; set;} // navigation attribute public BlogDetails Detail {get; set;} [Timestamp] public byte [] version {get; set ;}}

The test is as follows:

// Concurrently simulate Blog B = new Blog {ID = "24", BlogName = "Gaea", BlogAuthor = "shenwei", Detail = new BlogDetails {}}; // insert data through a ctx and submit using (BlogContext context = new BlogContext () {context. blogs. add (B); context. saveChanges () ;}// create the first data record of ctx, modify the data, but do not submit BlogContext fircontext = new BlogContext (); Blog firstblog = fircontext. blogs. firstOrDefault (); firstblog. blogName = "Haha, changed"; // create another ctx or retrieve the first data, modify and submit BlogContext secContext = new BlogContext (); Blog secondBlog = secContext. blogs. firstOrDefault (); secondBlog. blogAuthor = "JasonShen"; secContext. saveChanges (); // submit the modification try made by the first ctx at this time {// This is the current data, which has changed with the entry, so the fircontext error is returned. saveChanges (); Console. writeLine ("saved successfully");} catch (Exception e) {Console. writeLine ("failed to save");} Console. readKey ();}
The result is as follows: select * from Blogs;
The reason for capturing errors is that EF adds the fields identified by Timestamp to the where clause. After a piece of data is inserted at the beginning, the timestamp is like this. The first version of the object is like this. Later, the two context get the object, one of which is modified and submitted, at this time, the timestamp field in the database has changed. At this time, when another context is submitted, execute update... where version = 'initial version version' and then you will find that it cannot be found, so an error is reported! That is to say, the field marked by timespan is used to check whether the modification has occurred with the initial version. If so, an error is reported and an error is handled. What can EF do if an exception is caught? Use Reload to handle Resolving optimistic concurrency exceptions with Reload

Reload data is used as one of the policies to solve Optimistic Concurrency exceptions. In addition to Reload, there are several other conflict resolution policies.

One of the policies recommended by the Microsoft Entity Framework team to deal with optimistic concurrency conflicts is Reload data, that is, DbupdateConcurrencyException will be thrown when EF detects concurrency conflicts. In this case, the resolution conflicts are divided into Client Wins or Store Wins, the Reload processing, that is, Store Wins, means to discard the entity in the current memory and re-load the current entity in the database. The example code provided by the EF official team is as follows to catch exceptions:
Try {// This is the current data that has changed and just entered. Therefore, the fircontext error is returned. saveChanges (); Console. writeLine ("saved successfully");} catch (DbUpdateConcurrencyException e) {Console. writeLine ("failed to save"); Console. writeLine ("Reload"); e. entries. single (). reload (); Console. writeLine (firstblog. blogName); // the data value that is initially loaded from the database}
Concurrency for a single FieldIn some cases, you do not need to control the concurrency of the entire record. You only need to control the data in a column without any dirty operations. Then, you can use the ConcurrencyCheck flag.
   public class User    {        [Key ,DatabaseGenerated (DatabaseGeneratedOption .Identity)]        public Guid UserGuid { get; set; }        public string UserName { get; set; }               [ ConcurrencyCheck ]        public string certID { get; set; }    }
// ConcurrencyCheck concurrent User user = new User {UserName = "shenwei", certID = "11111"}; using (BlogContext ctx = new BlogContext ()) {ctx. users. add (user); ctx. saveChanges () ;}/// insert a piece of data first and submit // define two contexts to operate BlogContext firContext = new BlogContext (); User u1 = firContext. users. firstOrDefault (); BlogContext secContext = new BlogContext (); User u2 = secContext. users. firstOrDefault (); u2.certID = "22222"; // change the name and submit secContext. saveChanges (); try {u1.certID = "33333"; // another operation changes certid and also submits firContext. saveChanges ();} catch (Exception e) {Console. writeLine ("concurrent error ");}
Of course, you can use concurrentCheck to mark multiple fields at the same time, so that each marked field cannot be modified at the same time. The mechanism behind this is that the where field is used as the filter condition. SummaryAfter analysis, optimistic locks are not suitable for high-concurrency scenarios. A small amount of data conflicts are the original intention of optimistic concurrency. Pessimistic locks are also not suitable for handling high concurrency, especially when the lock cost is relatively high. If the project concurrency is indeed large, you can consider using other technologies, such as message queue. If you like this article, we recommend it!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.