Hibernate乐观锁和悲观锁

Hibernate支持两种锁机制: 即通常所说的“悲观锁(Pessimistic Locking)”和 “乐观锁(OptimisticLocking)”。

Hibernate的悲观锁加锁模式有:
1、LockMode.NONE : 无锁机制。
2、LockMode.WRITE :Hibernate在Insert和Update记录的时候会自动获取。
3、LockMode.READ : Hibernate在读取记录的时候会自动获取。
以上这三种锁机制一般由Hibernate内部使用,如Hibernate为了保证Update
过程中对象不会被外界修改,会在save方法实现中自动为目标对象加上WRITE锁。
Ø LockMode.UPGRADE :利用数据库的for update子句加锁。
Ø LockMode. UPGRADE_NOWAIT :Oracle的特定实现,利用Oracle的for update nowait子句实现加锁。


eg:

Emp e=(Emp)session.get(Emp.class, 10,LockMode.UPGRADE);语句:Hibernate:
select
emp0_.EMPNO as EMPNO0_0_,
emp0_.version as version0_0_,
emp0_.DEPTNO as DEPTNO0_0_,
emp0_.ENAME as ENAME0_0_,
emp0_.JOB as JOB0_0_,
emp0_.MGR as MGR0_0_,
emp0_.HIREDATE as HIREDATE0_0_,
emp0_.SAL as SAL0_0_,
emp0_.COMM as COMM0_0_
from
scott.emp emp0_
where
emp0_.EMPNO=? for update


加锁一般通过以下方法实现:

Criteria.setLockMode
Query.setLockMode
Session.lock
注意,只有在查询开始之前(也就是Hiberate 生成SQL 之前)设定加锁,才会 真正通过数据库的锁机制进行加锁处理,否则,数据已经通
过不包含for update 子句的Select SQL加载进来,所谓数据库加锁也就无从谈起。

XML配置:

<hibernate-mapping> <class name="org.han.entity.Dept" table="dept" schema="scott" optimistic-lock="version"> <id name="deptno" type="java.lang.Integer"> <column name="DEPTNO" precision="2" scale="0" /> <generator class="assigned" /> </id> <version name="version" type="java.lang.Integer"></version> <property name="dname" type="java.lang.String"> <column name="DNAME" length="14" /> </property> <property name="loc" type="java.lang.String" lazy="false"> <column name="LOC" length="13" /> </property> <set name="emps" inverse="true" fetch="select" lazy="true"> <key> <column name="DEPTNO" precision="2" scale="0" /> </key> <one-to-many class="org.han.entity.Emp" /> </set> </class> </hibernate-mapping>


实体类增加属性version:

private Integer deptno; private String dname; private String loc; private Integer version; private Set emps = new HashSet();

之后只要对数据库进行有意义的操作就会对version更新+1(version字段不能为空),事务提交前比较版本号是否一致


悲观锁与乐观锁的比较:
悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受;
相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。乐观锁机制往往基于系统中的数据存储逻辑,因此也具备一定的局限性,如在上例中,由于乐观锁机制是在我们的系统中实现,来自外部系统的更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。在
系统设计阶段,我们应该充分考虑到这些情况出现的可能性,并进行相应调整(如将乐观锁策略在数据库存储过程中实现,对外只开放基于此存储过程的数据更新途径,而不是将数据库表直接对外公开)。
Hibernate 在其数据访问引擎中内置了乐观锁实现。如果不用考虑外部系统对数据库的更新操作,利用Hibernate提供的透明化乐观锁实现,将大大提升我们的生产力。
Hibernate中可以通过class描述符的optimistic-lock属性结合version描述符指定。
optimistic-lock属性有如下可选取值:
Ø none
无乐观锁
Ø version
通过版本机制实现乐观锁
Ø dirty
通过检查发生变动过的属性实现乐观锁
Ø all
通过检查所有属性实现乐观锁
其中通过version实现的乐观锁机制是Hibernate官方推荐的乐观锁实现,同时也是Hibernate中,目前唯一在数据对象脱离Session发生修改的情况下依然有效的锁机制。因此,一般情况下,我们都选择version方式作为Hibernate乐观锁实现机制。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值