Go NHibernate Tour (7): A preliminary study of concurrency control in NHibernate

Source: Internet
Author: User

The content of this section

    • What is concurrency control?
      • Pessimistic concurrency control (pessimistic Concurrency)
      • Optimistic concurrency control (optimistic Concurrency)
    • NHibernate supports optimistic concurrency control
    • Example analysis
    • Conclusion
What is concurrency control?

When many people try to modify data in a database at the same time, a control system must be implemented so that changes made by one person do not adversely affect the changes made by others. This is called concurrency control.

A simple understanding is that 2 or more users edit the same data at the same time. The users here may be: The actual user, different services, different code snippets (using multithreading), and what can happen in the case of disconnection and connectivity.

Concurrency control theory is divided into two categories according to the method of establishing concurrency control:

Pessimistic concurrency control (pessimistic Concurrency)

A locking system that prevents users from modifying data in a way that affects other users. If the user performs an action that causes a lock to be applied, only the owner of the lock releases the lock, and the other user can perform the action that conflicts with that lock. This approach is called pessimistic concurrency control because it is primarily used in environments where data contention is intense, and when concurrency conflicts occur, the cost of protecting data with locks is lower than the cost of rolling back the transaction.

A simple understanding is usually done through an "exclusive lock" approach. Gets the lock to block access to the data that the other process is using. In other words, the reader and the writer are blocking each other, which can lead to data synchronization conflicts.

Optimistic concurrency control (optimistic Concurrency)

In optimistic concurrency control, data is not locked when the user reads the data. When a user updates the data, the system checks to see if the user has changed the data after reading the data. If other users update the data, an error is generated. In general, the user who receives the error message rolls back the transaction and starts over again. This approach is called optimistic concurrency control because it is used primarily in the following environments: Data contention is not large and the cost of occasionally rolling back a transaction is lower than the cost of locking the data when it is read.

(The above excerpt from the SQL Server2008 MSDN documentation)

NHibernate supports optimistic concurrency control

NHibernate provides a number of ways to support optimistic concurrency control: <version> nodes and <timestamp> nodes are defined in the mapping file. Where the <version> node is used for version control, indicating that the table contains data with version information. The <timestamp> node is used for time-intercept tracking, which indicates that the table contains timestamp data. Timestamps are essentially an implementation that is not particularly secure for optimistic locking. But in general, versioning is the preferred method. Of course, sometimes applications may use timestamps in other ways.

These two node mapping properties are shown in two images below:

To see what they mean:

    • Access (default property): NHibernate the policy used to access the attribute value.
    • Column (default is attribute name): Specifies the name of the field that holds the version number or the name of the field holding the timestamp.
    • Generated: Generate properties, optional never and always two properties.
    • Name: The attribute name of the persisted class or the specified type. The attribute name of the net type DateTime.
    • Type (default = Int32): Version number types, optional type Int64, Int32, Int16, Ticks, Timestamp, TimeSpan. Note that:<timestamp> and <version type= "timestamp" > are equivalent.
    • Unsaved-value (Default in version control is the "sensitive" value, which is null by default in time-truncation): Represents the version attribute value when an instance has just been instantiated (not yet saved), and depending on this value it can be distinguished from a free instance that has been saved or loaded in a previous session. (undefined indicates that the identity attribute value is used to determine)
Example analysis

Here's an example of optimistic concurrency control, where version versioning is used.

1. Modify the persisted customer class: Add the Version Property
public class customer{public    virtual int CustomerId {get; set;}    Version control public    virtual int Version {get; set;}    Public virtual string Firstname {get; set;}    Public virtual string Lastname {get; set;}}
2. Modify the mapping file: Add a version mapping node
<?xml version= "1.0" encoding= "Utf-8"? >version name= "version" column= "version "Type=" integer "unsaved-value=" 0 "/>    <property name=" Firstname "column =" Firstname "type=" string " Length= "not-null=" false "/>    <property name =" Lastname "column=" Lastname "type=" string "length=" 50 " Not-null= "false"/>  </class>
3. Modify the database to add the version field

Specific parameters: [Version] [int] not NULL default value is 1, of course, the modification of the database is the most primitive way, if you will use Schemaexport, you can directly use the persistence class and mapping files to generate the database, later in the introduction of how to use this.

4. Concurrent Update Testing

Before testing, let's look at what data is in the database and predict:

Write the Concurrency Update test code:

Query 2 times CustomerID for 1 of the customer, here is the first data above, the first modified to "Cnblogs", the second modified to "Www.cnblogs.com", both update the commit. What do you think happened?

[test]public void Updateconcurrencyviolationcanotthrowexception () {    Customer C1 = _transaction. Getcustomerbyid (1);    Customer C2 = _transaction. Getcustomerbyid (1);    C1. Name.firstname = "Cnblogs";    C2. Name.firstname = "www.cnblogs.com";    _transaction. Updatecustomertransaction (C1);    _transaction. Updatecustomertransaction (C2);}

Let's go to the database, at a glance:

We found that CustomerID has updated FirstName data for 1 of customers, and version has been updated to 2. Do you know what the principle is? Look at this step nhibernate generated SQL statements (I might be different than yours): Query the database, directly update the data, to see how nhibernate really, obviously did some optimization work.

SELECT customer0_. CustomerId as customerid3_0_, customer0_. Version as version3_0_, customer0_. Firstname as firstname3_0_,customer0_. Lastname as lastname3_0_,customer0_1_. Orderdiscountrate as orderdis2_4_0_, customer0_1_. CustomerSince as customer3_4_0_, case when     customer0_1_. CustomerId is isn't null then 1 when     customer0_. CustomerId is isn't null then 0 end as clazz_0_ from Customer customer0_ left outer join Preferredcustomer customer0_1_on CU stomer0_. Customerid=customer0_1_. CustomerId WHERE [email protected];  @p0 = ' 1 ' UPDATE Customer SET Version = @p0, Firstname = @p1, Lastname = @p2 WHERE CustomerId = @p3 and Version = @p4; @p0 = ' 2 ', @p1 = ' www.cnblogs.com ', @p2 = ' Lee ', @p3 = ' 1 ', @p4 = ' 1 '
5. Concurrent Delete test

Let's write a test again for concurrent deletion. Query 2 times CustomerID is 2 of the customer, here is the second data above, both delete data at the same time. What do you think happened?

[Test] [ExpectedException (typeof (Nhibernate.staleobjectstateexception))]public void Deleteconcurrencyviolationcanotthrowexception () {    Customer C1 = _transaction. Getcustomerbyid (2);    Customer C2 = _transaction. Getcustomerbyid (2);    _transaction. Deletecustomertransaction (C1);    _transaction. Deletecustomertransaction (C2);}

Similarly, look at the data in the database, the second data is missing.

The query statement that generates the SQL is the same as above, just a DELETE statement:

DELETE from Customer WHERE CustomerId = @p0 and Version = @p1; @p0 = ' 2 ', @p1 = ' 1 '

Well, here are two simple examples to illustrate the support for concurrency control in NHibernate. I believe that with a certain understanding, you can also write some interesting tests to try NHibernate optimistic concurrency control.

Go NHibernate Tour (7): A preliminary study of concurrency control in NHibernate

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.