Pessimistic lock and optimistic lock in hibernate

Source: Internet
Author: User

Pessimistic lock and optimistic lock in hibernate

Locking)
During the implementation of business logic, data access needs to be exclusive. For example, in the daily final computing process of the financial system, we want to process the data at a cut-off time point instead of the settlement process (which may be several seconds, or several hours), and the data changes again. At this point, we need to use some mechanisms to ensure that the data will not be modified by the outside world during an operation. Such a mechanism, here, is the so-called "Lock", that isLock the selected target data so that it cannot be modified by other programs.. Hibernate supports two lock mechanisms: Pessimistic locking and Optimistic Locking )".

I:Pessimistic lock(PessimisticLocking)
Pessimistic lock, as it is called, refers to a conservative attitude towards data being modified by the outside world (including other transactions of the current system, as well as transactions from the external system). Therefore, the data is locked during the entire data processing process. The implementation of pessimistic locks often relies on the lock mechanism provided by the database (Only the lock mechanism provided by the database layer can truly guarantee the exclusive data access.Otherwise, even if the locking mechanism is implemented in the system, the external system cannot modify the data ). A typical pessimistic lock call that relies on databases:Select * from account where name = "Erica" for update this SQL statement locks all records that meet the search criteria (name = "Erica") in the account table. Before the transaction is committed (the lock in the transaction process will be released when the transaction is committed), these records cannot be modified by the outside world.. The pessimistic lock of Hibernate is also implemented based on the database lock mechanism. The following code locks query records:

1 string hqlstr = "from Tuser as user where user. Name = 'erica '";
2 query = session. createquery (hqlstr );
3 query. setlockmode ("user", lockmode. Upgrade); // lock
4 List userlist = query. List (); // execute the query,

 

Get DataQuery. setlockmodeLock the record corresponding to a specific alias in the query statement (we have specified an alias "user" for the Tuser class). Here, all the returned user records are locked. Observe the SQL statements generated by hibernate during runtime:

 

1 select tuser0 _. ID as ID, tuser0 _. name as name, tuser0 _. group_id as group_id, tuser0 _. user_type as user_type, tuser0 _. sex as sex from t_user tuser0 _ Where (tuser0 _. name = 'erica ') for update

 

Here, Hibernate uses the for update clause of the database to implementPessimistic lockMechanism. The locking modes of hibernate include:
? Lockmode. None: No lock mechanism.
? Lockmode. Write: hibernate will automatically obtain the insert and update records.
? Lockmode. Read: hibernate automatically obtains the data when reading the record.

The above three lock mechanisms are generally used internally by hibernate. For example, in order to ensure that objects in the update process are not modified by the outside world, Hibernate will automatically add the write lock to the target object in the implementation of the Save method.

? Lockmode. Upgrade:Lock by using the for update clause of the database.
? Lockmode. upgrade_nowait: specific implementation of Oracle,Use Oracle's for update Nowait clause to implement locking.

The above two locking mechanisms are commonly used at the application layer. The locking is generally implemented through the following methods:
Criteria. setlockmode
Query. setlockmode
Session. Lock
Note: Only when the lock is set before the query starts (that is, before the hiberate generates the SQL statement) Will the database lock mechanism be used for the lock process. Otherwise, data has been loaded through select SQL that does not contain the for update clause. The so-called database locking is impossible.

**************************************** ******

The database locks implemented based on JDBC are as follows:

Select * from account where name = "Erica" for update

During the update process, the database is locked, and any other operations on this data will be delayed. This transaction is unlocked after being committed.
Hibernate pessimistic locks are implemented as follows:
String SQL = "query statement ";
Query query = session. createquery (SQL );
Query. setlockmode ("object", lockmodel. Upgrade );

Here, we mention the hibernate locking mode:

Lockmode. None: No lock mechanism.
Lockmode. Write: hibernate will automatically obtain the insert and update records.
Lockmode. Read: hibernate automatically obtains the data when reading the record.

These three locking modes are used internally by Hibernate and are irrelevant to database locking:

Lockmode. Upgrade: Use the for update statement of the database to add a lock.

Here, we should note that the database lock mechanism can be used only when the lock is applied before the query starts (that is, before hive generates an SQL statement. Otherwise, the data has been loaded through an SQL statement that does not contain the for updata clause, so the so-called database locking is impossible.
However, considering the system performance, this is not a problem for a single or small system. However, if it is a system on the network, there will be a lot of connections at the same time, what should we do if hundreds or even thousands of concurrent accesses occur? If we wait until the database is unlocked before performing the following operations, what resources are wasted? -- This leads to the emergence of optimistic locks.

 

 

2. Optimistic Locking)
Compared with pessimistic locks, optimistic locks adopt a more loose locking mechanism. Pessimistic locks are implemented based on the database lock mechanism in most cases to ensure maximum operation exclusiveness. However, there is a large amount of database performance overhead, especially for long transactions, which is often unbearable. For example, in a financial system, when an operator reads user data and performs Modification on the basis of the read user data (such as changing the user account balance), if a pessimistic lock mechanism is used, this means that the database record is always locked throughout the entire operation process (from the operator reading data, starting modification to submitting modification results, or even the time when the operator goes to coffee preparation, we can imagine what the consequences would be if we were dealing with hundreds of thousands of concurrent jobs. The Optimistic Locking Mechanism solves this problem to some extent.Optimistic locks are mostly implemented based on the data version record mechanism.. What is the data version? Add a version ID for the data. In the database table-based version solution, you can add a "version" field to the database table. When reading the data, read the version number together, and then add one to the version number when updating the data. In this case, the version data of the submitted data is compared with the current version information recorded in the database table. If the submitted data version number is greater than the current version number of the database table, it is updated, otherwise, expired data is considered. For the example of modifying user account information above, assume:

The account information table in the database has a version field. The current value is 1, and the current account balance field (balance) is $100.
1: operator A reads it (version = 1) and deducts $50 ($100-$50) from its account balance ).
2: During operator A's operations, operator B also reads this user information (version = 1) and deducts $20 ($100-$20) from its account balance ).
3: operator A completes the modification and submits the data version number plus one (version = 2), along with the account balance deducted (balance = $50) to the database for updates, at this time, because the submitted data version is larger than the current version of the database record, the data is updated, and the database record version is updated to 2.
4: Operator B completes the operation and tries to submit data (balance = $80) to the database with version 1 (version = 2). However, when comparing the database version, the version number of the data submitted by operator B is 2, and the current version of the database record is 2, which does not meet the optimistic lock policy of "The submitted version must be later than the current version to be updated". Therefore, the submission of operator B is rejected. This avoids the possibility that operator B overwrites the operation result of operator A with the old data modification Result Based on version = 1.

From the above example, we can see that the Optimistic Locking mechanism avoids the database lock overhead in long transactions (no database data lock is applied during operator A and operator B operations ), this greatly improves the overall performance of the system with a large concurrency. It should be noted that the Optimistic Locking Mechanism is often based on the data storage logic in the system, so it also has certain limitations, as in the above example, the Optimistic Locking mechanism is implemented in our system. The updating of user balance from the external system is not controlled by our system, so dirty data may be updated to the database. In the system design phase, we should fully consider the possibility of such situations and make appropriate adjustments (for example, implementing Optimistic Locking policies in database storage processes, only the data update path based on this stored procedure is open to the outside, rather than the database table is open to the outside ).Hibernate has built-in optimistic lock implementation in its data access engine.. If you do not need to consider the update operation of the external system's logarithm database, using the transparent optimistic lock provided by hibernate will greatly improve our productivity. In hibernate, the optimistic-lock attribute of the class descriptor can be used together with the version descriptor.
Now, we add an optimistic lock mechanism to the Tuser in the previous example.

1. First, add the optimistic-lock attribute for the Tuser class descriptor:

<Hibernate-mapping>
<Class
Name = "org. hibernate. sample. Tuser"
Table = "t_user"
Dynamic-update = "true"
Dynamic-insert = "true"
Optimistic-lock = "version"
>
......
</Class>
</Hibernate-mapping>

 

The optimistic-lock attribute has the following optional values:
? None No optimistic lock
? Version implements optimistic locks through the version Mechanism
? Dirty implements Optimistic Locking by checking changed attributes
? All is implemented by checking all attributes

 

Next we will test the hibernate optimistic Lock Based on the previous example.

First, you need to modify the business object previously implemented and add a version attribute to it to record the version information of the data contained in the object. The modified User object is shown in listing 14.5.

User object modified in listing 14.5

Package CN. hxex. hibernate. lock;

Public class user {

Private string ID;

Private integer version; // adds the version attribute.

Private string name;

Private integer age;

// The getter and setter methods are omitted.

......

}

Then, modify the ing file and add the version attribute configuration. Note that the version attribute should be configured with a special <version> element to enable Optimistic Locking. If you still use the <property> element for configuration, Hibernate will only process it as a common property.

Modified ing File

<? XML version = "1.0"?>

<! Doctype hibernate-mapping public

"-// Hibernate/hibernate mapping DTD 3.0 // en"

Http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>

<Hibernate-mapping package = "cn. hxex. hibernate. Lock">

<Class name = "user" table = "userinfo" optimistic-lock = "version">

<ID name = "ID" column = "userid">

<Generator class = "UUID. Hex"/>

</ID>

<Version name = "version" column = "version" type = "Java. Lang. Integer"/>

<Property name = "name" column = "name" type = "Java. Lang. String"/>

<Property name = "Age" column = "Age" type = "Java. Lang. Integer"/>

</Class>

</Hibernate-mapping>

 

 

 

**************************************** *********

Optimistic Locking is optimistic that data access rarely occurs at the same time, so it is not locked at the database level. In order to maintain the correct data, optimistic Locking adopts the logic of the application to implement version control.

For example, if there are two clients, customer a first reads the account balance of 100 yuan, and customer B also reads the data of the account balance of 100 yuan. Customer A extracts 50 yuan, after the database is changed, the balance in the database is 50 yuan, and customer B needs to withdraw 30 yuan. According to the information obtained, the balance between and 30 will be 70, if you change the database at this time, the final balance will be incorrect.

When the pessimistic locking policy is not implemented, data inconsistency occurs. There are several solutions: update first and update later, it is complicated to check the changed data or check all attributes for Optimistic Locking.

Hibernate implements post-update based on version number check, which is also recommended by hibernate. It adds a Verson column record to the database to read data together with the version number, increase the version number when updating data, and then compare the version number with the version number in the database. if the version number is greater than the version number in the database, update the version number. Otherwise, an error is returned.

In the preceding example, If Customer A reads the account balance of 1000 yuan and the version number is 5, Customer B also reads the account balance of 1000 yuan, and the version number is also 5, customer A's account balance is 500 after receiving the payment. In this case, the version number is added to 1. The current version number is 6, and the database version number is 5. Therefore, after updating the database, the database balance is 500, the version number is 6, and the database needs to be changed after Customer B receives the payment. The database version number is 5, but the database version number is 6, which is not updated at this time, b. The database is changed only when customer data is re-read from the database and business processes are re-performed.

When Hibernate is used to implement version control lock, we add a version attribute to our object, for example:

Public class account {
Private int version;
....
Public void setversion (INT version ){
This. Version = version;
}
Public int getversion (){
Return version;
}
....
}

In the image file, we use the optimistic-lock attribute to set version control, and add a <version> label after the <ID> attribute bar, as shown below:

<Hibernate-mapping>
<Class name = "onlyfun. Caterpillar. Account" talble = "Account"
Optimistic-lock = "version">
<ID.../>
<Version name = "version" column = "version"/>
....
</Class>
</Hibernate-mapping>

After version control is set, If Customer B tries to update the data in the preceding example, the stableobjectstateexception is thrown. We can capture this exception and re-read the data in the database during processing, at the same time, the current data of Customer B and the data in the database are presented, giving Customer B the opportunity to compare the inconsistent data to determine the part to be changed, alternatively, you can design a program to automatically read new data and repeat the deduction business process until the data can be updated, which can be performed on the background without the need for your customers to know.

But optimistic locks cannot be solved: The implementation of optimistic locks is often implemented in our system based on the data storage logic in the system, updates of user balances from external systems are not controlled by our system, and illegal data may be updated to the database. Therefore, when doing e-commerce, we must pay attention to this problem and adopt reasonable logic verification to avoid data execution errors.

You can also specify the lock mode when using session load () or lock () to lock the session.

If the database does not support the specified locking mode, Hibernate will choose an appropriate locking replacement instead of dropping an exception.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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.