hibernate 乐观锁

 Hibernate支持乐观锁。当多个事务同时对数据库表中的同一条数据操作时,如果没有加锁机制的话,就会产生脏数据(duty data)。Hibernate有2种机制可以解决这个问题:乐观锁和悲观锁。这里我们只讨论乐观锁。 
     Hibernate乐观锁,能自动检测多个事务对同一条数据进行的操作,并根据先胜原则,提交第一个事务,其他的事务提交时则抛出org.hibernate.StaleObjectStateException异常。 
    Hibernate乐观锁是怎么做到的呢? 
    我们先从Hibernate乐观锁的实现说起。要实现Hibenate乐观锁,我们首先要在数据库表里增加一个版本控制字段,字段名随意,比如就叫version,对应hibernate类型只能为 long,integer,short,timestamp,calendar,也就是只能为数字或timestamp类型。然后在hibernate mapping里作如下类似定义: 

    <version name="version" 
        column="VERSION" 
        type="integer"/> 

告诉Hibernate version作为版本控制用,交由它管理。 
当然在entity class里也需要给version加上定义,定义的方法跟其他字段完全一样。 
private Integer version; 
… 
// setVersion() && getVersion(Integer) 

Hibernate乐观锁的的使用: 
Session session1 = sessionFactory.openSession(); 
Session session2 = sessionFactory.openSession(); 
MyEntity et1 = session1.load(MyEntity.class, id); 
MyEntity et2 = session2.load(MyEntity.class, id); 
//这里 et1, et2为同一条数据 
Transaction tx1 = session1.beginTransaction(); 
//事务1开始 
et1.setName(“Entity1”); 
//事务1中对该数据修改 
tx1.commit(); 
session1.close(); 
//事务1提交 
Transaction tx2 = session2.beginTransaction(); 
//事务2开始 
et2.setName(“Entity2”); 
//事务2中对该数据修改 
tx2.commit(); 
session2.close(); 
//事务2提交 

在事务2提交时,因为它提交的数据比事务1提交后的数据旧,所以hibernate会抛出一个org.hibernate.StaleObjectStateException异常。 
回到前面的问题,Hibernate怎么知道事务2提交的数据比事务1提交后的数据旧呢? 
因为MyEntity有个version版本控制字段。 

回头看看上面的源代码中的: 
MyEntity et1 = session1.load(MyEntity.class, id); 
MyEntity et2 = session2.load(MyEntity.class, id); 
这里,et1.version==et2.version,比如此时version=1, 
当事务1提交后,该数据的版本控制字段version=version+1=2,而事务2提交时version=1<2所以Hibernate认为事务2提交的数据为过时数据,抛出异常。 
这就是Hibernate乐观锁的原理机制。 
我们已经知道了Hibernate乐观锁是根据version的值来判断数据是否过时,也就是说,在向数据库update某数据时,必须保证该entity 里的version字段被正确地设置为update之前的值,否则hibernate乐观锁机制将无法根据version作出正确的判断。 
在我们的WEB应用中,尤其应该注意这个问题。

转自:http://blog.csdn.net/vean_system/article/details/7539401

让我们看看文档

When using long transactions or conversations that span several database transactions, it is useful to store versioning data to ensure that if the same entity is updated by two conversations, the last to commit changes will be informed and not override the other conversation's work. It guarantees some isolation while still allowing for good scalability and works particularly well in read-often write-sometimes situations.

注意这句the last to commit changes will be informed and not override the other conversation's work,就是说后面更新的不能覆盖之前更新的,也就是转载说的:当事务1提交后,该数据的版本控制字段version=version+1=2,而事务2提交时version=1<2所以Hibernate认为事务2提交的数据为过时数据,抛出异常。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值