About the locking mechanism of hibernate

Regarding the locking mechanism in hibernate, I saw GOING MM's description of Hibernate Transaction a few days ago. Here is an article on the locking mechanism in hiberntae: 

   pessimistic locking assumes that when data is accessed at any time, there may be another client. The same data is taken, so the data is locked at the database level. During the locked time, other clients cannot access the data. For a single machine or small system, this is not a problem. However, if it is on the network In the system, there will be many connections at the same time. If every time the data is read, it will cause a lock, and the subsequent access will have to wait, which will cause performance problems and cause the subsequent users to wait for a long time. 
 Optimistic locking (optimistic locking) optimistically believes that data access rarely occurs at the same time, so it does not lock at the database level. In order to maintain correct data, optimistic locking uses application logic to achieve version control solutions. . 
 For example, if there are two clients, customer A first reads the account balance of 1,000 yuan, then customer B also reads the data of the account balance of 1,000 yuan, and customer A withdraws 500 yuan and makes changes to the database. The balance of customer B is 500 yuan, and customer B also needs to withdraw 300 yuan. According to the information obtained, 1000-300 will be 700 yuan. If the database is changed at this time, the final balance will be incorrect. 
 In the case of not implementing the pessimistic locking strategy, once the data inconsistency occurs, there are several solutions. One is to update first, the other is to update later, and the more complicated one is to check for changes. data, or check all properties for optimistic locking. 
 In Hibernate, the version number check is used to achieve the main update, which is also recommended by Hibernate. Add a VERSON column record to the database, read it together with the version number when reading data, and increment the version when updating data. number, and then compare the version number with the version number in the database, if it is greater than the version number in the database, update it, otherwise report an error. 
 Taking the example just now, if customer A reads the account balance of 1,000 yuan and reads the version number as 5, customer B also reads the account balance of 1,000 yuan and the version number is 5. Customer A has the account balance after receiving the money. It is 500. At this time, the version number is increased by 1. The version number is currently 6, and the version number in the database is 5, so it is updated. After updating the database, the database balance is now 500, and the version number is 6. After customer B receives the payment To change the database, its version number is 5, but the version number of the database is 6, and it will not be updated at this time. The B client data re-reads the new data in the database and re-runs the business process to change the database. 
 To implement version control locking with Hibernate, add a version attribute to our object, for example: 

Java code   Favorite code
  1. public class Account {  
  2.   
  3.     private int version;  
  4.   
  5.     ....  
  6.   
  7.    
  8.   
  9.     public  void  setVersion( int  version) {  
  10.   
  11.         this.version = version;  
  12.   
  13.     }  
  14.   
  15.    
  16.   
  17.     public int getVersion() {  
  18.   
  19.         return version;  
  20.   
  21.     }  
  22.   
  23.     ....  
  24.   
  25. }  




In the image file, we use the optimistic-lock attribute to set the version control, and add a <version> tag after the <id> attribute column, for example:

Java code   Favorite code
  1. <hibernate-mapping>  
  2.   
  3.     <class name="onlyfun.caterpillar.Account" talble="ACCOUNT"  
  4.   
  5.            optimistic-lock="version">  
  6.   
  7.         <id...../>  
  8.   
  9.         <version name="version" column="VERSION"/>  
  10.   
  11.    
  12.   
  13.          ....  
  14.   
  15.    
  16.   
  17.     </class>  
  18.   
  19. </hibernate-mapping>  




 设定好版本控制之后,在上例中如果B客户试图更新数据,将会引发StableObjectStateException例外,我们可以捕捉这个例外,在处理中重新读取数据库中的数据,同时将B客户目前的数据与数据库中的数据秀出来,让B客户有机会比对不一致的数据,以决定要变更的部份,或者您可以设计程 式自动读取新的资料,并重复扣款业务流程,直到数据可以更新为止,这一切可以在背景执行,而不用让您的客户知道。 



  悲观锁定在多个客户端可能读取同一笔数据或同时更新一笔数据的情况下,必须要有访问控制的手段,防止同一个数据被修改而造成混乱,最简单的手段就是对数据进行锁定,在自己进行数据读取或更新等动作时,锁定其它客户端不能对同一笔数据进行任何的动作。 
 悲观锁定(Pessimistic Locking)一如其名称所示,悲观的认定每次资料存取时,其它的客户端也会存取同一笔数据,因此对该笔数据进行锁定,直到自己操作完成后解除锁定。 
 悲观锁定通常透过系统或数据库本身的功能来实现,依赖系统或数据库本身提供的锁定机制,Hibernate即是如此,我们可以利用Query或Criteria的setLockMode()方法来设定要锁定的表或列(row)及其锁定模式,锁定模式有以下的几个: 

LockMode.WRITE:在insert或update时进行锁定,Hibernate会在save()方法时自动获得锁定。 
LockMode.UPGRADE:利用SELECT … FOR UPDATE进行锁定。 
LockMode.UPGRADE_NOWAIT:利用SELECT … FOR UPDATE NOWAIT进行锁定,在Oracle环境下使用。 
LockMode.READ:在读取记录时Hibernate会自动获得锁定。 
LockMode.NONE: No locking. 
 You can also specify the lock mode for locking when using Session's load() or lock(). 
 If the database does not support the specified locking mode, Hibernate will choose an appropriate locking replacement instead of throwing an exception (Hibernate Reference Manual 10.6). 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326708625&siteId=291194637