Hibernate的悲观锁与乐观锁

Hibernate提供了两种锁机制,悲观锁和乐观锁。

1.悲观锁

其中悲观锁的实现依赖于数据库的锁机制,如果数据库底层没有实现相应的数据排他性,那么就无法实现悲观锁。

加锁模式有:

LockMode.None 不加锁

LockMode.Write 在insert和update的时候会自动获取 / /还是不明白的因为没有用过

LockMode.Read 在读取数据的时候自动获取 /还是不明白的因为没有用过

以上三种都是在Hibernate内部进行使用的。

LockMode.UPGRADE是利用数据库的select..... for update语句进行加锁的。

LockMode. UPGRADE_NOWAIT :Oracle的特定实现,利用Oracle的for update nowait子句实现加锁

以下是编程实现的语句:

String hql = "from Tuser as user where user.name='maojiangege'";

Query query = session.createQuery(hql);

query.setLockMode(“user",LockMode.UPGRADE);

List list = query.list();

获取数据 query.setLockMode 对查询语句中特定别名所对应的记录进行加锁(我们为 TUser类指定了一个别名“user”),这里也就是对返回的所有user记录进行加锁。 观察运行期Hibernate生成的SQL语句:

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

这里Hibernate通过使用数据库的for update子句实现了悲观锁机制。

上面这两种锁机制是我们在应用层较为常用的,加锁一般通过以下方法实现:

Criteria.setLockMode

Query.setLockMode

Session.lock

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

2.乐观锁

乐观锁其实并不是一种锁,它其实是一种检查机制。它一般是基于数据库的版本记录来实现的version,在数据库的表中增加一个字段version,当我们读取数据的时候将数据库的版本一块读取,当我们进行更新数据的时候它会检查数据库的版本,如果版本比我们查到的版本高,则认为数据已经过期,不予更新,相反则可以进行更新。

配置代码:
< hibernate - mapping >
2 < class
3 name = " org.hibernate.sample.TUser "
4 table = " t_user "
5 dynamic - update = " true "
6 dynamic - insert = " true "
7 optimistic - lock = " version "
8 >
9 < id
10 name = " id "
11 column = " id "
12 type = " java.lang.Integer "
13 >
14 < generator class = " native " >
15 </ generator >
16 </ id >
17 < version
18 column = " version "
19 name = " version "
20 type = " java.lang.Integer "
21 />
22 ……
23 </ class >
24 </ hibernate - mapping >
25



悲观锁与乐观锁的比较:
悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受;
相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。乐观锁机制往往基于系统中的数据存储逻辑,因此也具备一定的局限性,如在上例中,由于乐观锁机制是在我们的系统中实现,来自外部系统的更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。在
系统设计阶段,我们应该充分考虑到这些情况出现的可能性,并进行相应调整(如将乐观锁策略在数据库存储过程中实现,对外只开放基于此存储过程的数据更新途径,而不是将数据库表直接对外公开)。
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、付费专栏及课程。

余额充值