The role of optimistic locking

Source: Internet
Author: User
Tags generator uuid
The role of optimistic locking

The main function of optimistic lock is to solve the problem caused by transaction concurrency. In contrast to pessimistic lock, the optimistic locking mechanism adopts a more relaxed locking mechanism.

Pessimistic lock in most cases rely on the database lock mechanism to achieve the maximum degree of exclusivity to ensure the operation. But then comes the massive cost of database performance, especially for long transactions, which are often unsustainable. The optimistic locking mechanism solves this problem to some extent. Optimistic locks, most of which are based on data Versioning (version) recording mechanism implementations. What is the data version. That is, adding a version identity to the data, in a version solution based on a database table, typically by adding a "version" field to the database table.

The working principle of optimistic lock

When you read out the data, read the version number together, and then when you update it, add one to this version number. At this point, the version data for the submitted data is compared to the current version information of the corresponding record in the database table, and is updated if the submitted data version number is greater than the current version number of the database table, otherwise it is considered to be an expired data.

Optimistic lock implementation based on Hibernate

Optimistic lock implementation based on hibernate generally has the following two kinds of methods

Based on timestamp based on version

Here's an introduction to optimistic lock implementation based on version

XML code <?xmlVersion= "1.0" ?><! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" "Http://hibernate.source Forge.net/hibernate-mapping-3.0.dtd " > <className= "Test. Dir "table=" T_dir " > <idName= "id" type= "string" unsaved-value= "null" > <columnName= "Id_" sql-type= "char" not-null= "true" /> <generatorClass= "Uuid.hex" /> </id> <versionColumn= "Version_" name= "version" /> <propertyName= "name" column= "Name_" type= "string" /> <propertyName= "Size" column= "Size_" type= "Long" /> <many-to-oneName= "dir" column= "pid_" class= "test." Dir " /> </class>
<?xml version= "1.0"?>
<! DOCTYPE hibernate-mapping public
        "-//hibernate/hibernate mapping DTD 3.0//en"
        "http:// Hibernate.sourceforge.net/hibernate-mapping-3.0.dtd ">


Note here that the version's position must be placed behind the ID

Problems caused by optimistic locks

When two different transactions are read and modified at the same time, the program throws Org.hibernate.StaleObjectStateException:Row is updated or deleted by another Transaction (or Unsaved-value mapping was incorrect) exception.

There are two things here, too.

One is the case of two different transactions

Java code   @Test    public void testtransation1 () {        session session1 = null;       Session session2 =  null;       try{            Session1 = hibernateutil.getsession ();            Session2 = hibernateutil.getsession ();            dir dir1 =  (Dir) session1.load (dir.class,  "4028811a3d3387d3013d3387d4a40008");           Dir dir2 =  (Dir) session2.load (dir.class,  " 4028811a3d3387d3013d3387d4a40008 ");           transaction  tx1 = session1.begintransaction ();            Dir1.setsize (1111);           tx1.commit ();            transaction tx2 = session2.begintransaction ();            dir2.setsize (999);            tx2.commit ();           system.out.println ("Transaction 2 commit ");       }catch (exception e) {            e.printstacktrace ();       }finally{            if (session1 != null) {                session1.close ();            }           if (session2 != null) {    &NBSP;&NBSP;          session2.close ();            }       }  }  
	@Test public
	void TestTransation1 () {session
		session1 = null;
		Session session2 = NULL;
		try{
			session1 = hibernateutil.getsession ();
			Session2 = Hibernateutil.getsession ();
			Dir dir1 = (dir) session1.load (Dir.class, "4028811a3d3387d3013d3387d4a40008");
			Dir dir2 = (dir) session2.load (Dir.class, "4028811a3d3387d3013d3387d4a40008");
			Transaction tx1 = Session1.begintransaction ();
			Dir1.setsize (1111);
			Tx1.commit ();
			Transaction tx2 = Session2.begintransaction ();
			Dir2.setsize (999);
			Tx2.commit ();
			System.out.println ("Transaction 2 Commit");
		} catch (Exception e) {
			e.printstacktrace ();
		} finally{
			if (session1!= null) {
				session1.close ();
			}
			if (session2!= null) {
				session2.close ();}}}
	


Transaction 2 When the value of version is found to be different, this time it throws Org.hibernate.StaleObjectStateException:Row is updated or deleted by another Transaction (or Unsaved-value mapping was incorrect) exception


The second case is the case of a child transaction
Java code   @Test    public void testtransation5 () {        session session1 = null;       Session session2 =  null;       try{            Session1 = hibernateutil.getsession ();            Session2 = hibernateutil.getsession ();            dir dir1 =  (Dir) session1.load (dir.class,  "4028811a3d3387d3013d3387d4a40008");           Dir dir2 =  (Dir) session2.load (dir.class,  " 4028811a3d3387d3013d3387d4a40008 ");           transaction  tx1 = session1.begintransaction ();            transaction Tx2 = session2.begintransaction ();            Dir2.setsize (7777);           tx2.commit ();            dir1.setsize (3333);            tx1.commit ();       }catch (exception e) {            e.printstacktrace ();       }finally{            if (session1 != null) {                session1.close ();            }           if (session2 !=  null) {               session2.close ();  &nbSp         }       }  }   
	@Test public
	void TestTransation5 () {session
		session1 = null;
		Session session2 = NULL;
		try{
			session1 = hibernateutil.getsession ();
			Session2 = Hibernateutil.getsession ();
			Dir dir1 = (dir) session1.load (Dir.class, "4028811a3d3387d3013d3387d4a40008");
			Dir dir2 = (dir) session2.load (Dir.class, "4028811a3d3387d3013d3387d4a40008");
			Transaction tx1 = Session1.begintransaction ();
			Transaction tx2 = Session2.begintransaction ();
			Dir2.setsize (7777);
			Tx2.commit ();
			Dir1.setsize (3333);
			Tx1.commit ();
		} catch (Exception e) {
			e.printstacktrace ();
		} finally{
			if (session1!= null) {
				session1.close ();
			}
			if (session2!= null) {
				session2.close ();}}}
	


We found that 2 of things are wrapped in transaction 1, if DIR is configured to delay loading (hibnernate default is delayed loading), this time when the transaction 1 commits, will go to the database to query, and then update operations.

If DIR is configured to not delay loading (lazy= "false"), then transaction 1 does not query the database at the time of submission, but submits it directly and finds version mismatch at the time of submission. It will also throw Org.hibernate.StaleObjectStateException:Row is updated or deleted by another transaction (or Unsaved-value Mappin G was incorrect) exception

Solutions

1, Catch staleobjectstateexception exception, prompted the data obsolete has been modified to allow users to resubmit

2, as far as possible from the business to reduce transaction block, the larger the transaction block, by the optimistic lock caused by the greater the probability of the problem

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.