Hibernate乐观锁

Hibernate支持乐观锁。当多个事务同时对数据库表中的同一条数据操作时,如果没有加锁机制的话,就会产生脏数据(duty data)。Hibernate有2种机制可以解决这个问题:乐观锁和悲观锁。这里我们只讨论乐观锁。

  Hibernate乐观锁,能自动检测多个事务对同一条数据进行的操作,并根据先胜原则,提交第一个事务,其他的事务提交时则抛出org.hibernate.StaleObjectStateException异常。

  Hibernate乐观锁是怎么做到的呢?

  我们先从Hibernate乐观锁的实现说起。要实现Hibenate乐观锁,我们首先要在数据库表里增加一个版本控制字段,字段名随意,比如就叫version,对应hibernate类型只能为 long,integer,short,timestamp,calendar,也就是只能为数字或timestamp类型。然后在hibernate mapping里作如下类似定义:

  

Xml代码   收藏代码
  1. <version name="version"  
  2.     column="VERSION"  
  3.     type="integer"  
  4.   />  

 

  告诉Hibernate version作为版本控制用,交由它管理。

  当然在entity class里也需要给version加上定义,定义的方法跟其他字段完全一样。

  

Java代码   收藏代码
  1. private Integer version;  
  2.   …  
  3. // setVersion() && getVersion(Integer)  

 

 Hibernate乐观锁的的使用:

Java代码   收藏代码
  1. Session session1 = sessionFactory.openSession();  
  2. Session session2 = sessionFactory.openSession();  
  3. MyEntity et1 = session1.load(MyEntity.class, id);  
  4. MyEntity et2 = session2.load(MyEntity.class, id);  
  5. //这里 et1, et2为同一条数据  
  6. Transaction tx1 = session1.beginTransaction();  
  7. //事务1开始  
  8. et1.setName(“Entity1”);  
  9. //事务1中对该数据修改  
  10. tx1.commit();  
  11. session1.close();  
  12. //事务1提交  
  13. Transaction tx2 = session2.beginTransaction();  
  14. //事务2开始  
  15. et2.setName(“Entity2”);  
  16. //事务2中对该数据修改  
  17. tx2.commit();  
  18. session2.close();  
  19. //事务2提交  

 

  在事务2提交时,因为它提交的数据比事务1提交后的数据旧,所以hibernate会抛出一个org.hibernate.StaleObjectStateException异常。

  回到前面的问题,Hibernate怎么知道事务2提交的数据比事务1提交后的数据旧呢?

  因为MyEntity有个version版本控制字段。

  回头看看上面的源代码中的:

  

Java代码   收藏代码
  1. MyEntity et1 = session1.load(MyEntity.class, id);  
  2. MyEntity et2 = session2.load(MyEntity.class, id);  
  3.   这里,et1.version==et2.version,比如此时version=1,  
  4.   当事务1提交后,该数据的版本控制字段version=version+1=2,而事务2提交时version=1<2所以Hibernate认为事务2提交的数据为过时数据,抛出异常。  

 

  这就是Hibernate乐观锁的原理机制。

  我们已经知道了Hibernate乐观锁是根据version的值来判断数据是否过时,也就是说,在向数据库update某数据时,必须保证该entity 里的version字段被正确地设置为update之前的值,否则hibernate乐观锁机制将无法根据version作出正确的判断。

  在我们的WEB应用中,尤其应该注意这个问题。

 

图示:

1.映射文件:

 

2.实体类:

 

3.DAO:

 

4.Service:

 

5.Action:

 

6.页面:

 

http://zyjustin9.iteye.com/blog/2090285

猜你喜欢

转载自aoyouzi.iteye.com/blog/2387994