`
里克尔奇
  • 浏览: 36222 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate中的悲观锁(pessimistic lock)和乐观锁(optimistic lock)

阅读更多

Hibernate 中的悲观锁( pessimistic lock )和乐观锁( optimistic lock

悲观锁( pessimistic lock ):

通常是由数据库机制实现的,在整个过程中把数据锁住(查询时),只要事务不释放(提交或回滚),任何用户都不能查看和修改。锁主要是解决并发性问题。

通过 jdbc 实现时 sql 语句只要在整个语句之后加 for update 即可。例如: select …for update

Hibernate 中加载一个持久化类时需要用 load 方法 这个方法是对普通的 load 的重载。

如: Student inv= Student session.load(Student .class,”1001”,LOCKMODE.UPGRADE);

这时需要说明一个问题,这样就加了锁锁的类型可以根据 LOCKMODE 的值决定。加了锁之后, Hibernate lazy 策略就失效了,此时就发了 sql 语句,因为需要把这个对象加载进来锁住,所以发了 SQl 语句。当有一个方法通过悲观锁机制加载某个对象的时候,对这个对象进行了一系列的操作,在进行操作的时候,也就是只要事务未提交,这个锁就一直存在。当另外一个方法加载这个对象的时候(两个对象是一个对象,即唯一标示符的值是相同的)只会发出查询语句,停止不动,因为,前一个方法使用了悲观锁机制加载的这个对象,并没有结束事务(提交或回滚),因此这时是排他的。当第一个方法提交了事务,第二个方法才可以加载成功并按照自己的意愿执行其所有操作。

悲观锁的使用:悲观锁解决了更新丢失( lost update )问题,但是也带来了并发问题 à 并发不好。但是,如果在某个需求中,需要很多,很频繁的并发操作,特别是,某个操作或事务又会占用很多时间时,其他操作只能静而后之了。要看具体应用了。

Hibernate 的加锁模式有:

Ø LockMode.NONE 无锁机制。

Ø LockMode.WRITE Hibernate Insert Update 记录的时候会自动

获取。
Ø LockMode.READ
Hibernate 在读取记录的时候会自动获取。

以上这三种锁机制一般由 Hibernate 内部使用,如 Hibernate 为了保证 Update

过程中对象不会被外界修改,会在 save 方法实现中自动为目标对象加上 WRITE 锁。

Ø LockMode.UPGRADE :利用数据库的 for update 子句加锁。

Ø LockMode. UPGRADE_NOWAIT Oracle 的特定实现,利用 Oracle for

update nowait 子句实现加锁。

乐观锁( optimistic ):

乐观锁其实不是一种锁,也就不是锁住的问题,而是给数据库表加入了一个字段(可以使版本号( version ),也可以使一个时间戳( timestamp )),或是进行全部字段 / 脏数据字段比较(这种方式适合于以前遗留下来的系统,在不更改原来表结构的时候使用这种策略)来确定数据是否被修改过,一般的应用是采用数据版本的方式( version )实现,在读取数据的时候将 version 读取出来,在保存数据的时候判断 version 的值是否小于数据库中的 version 的值,小于则不允许更新,否则可以更新。

使用 version 实现乐观锁(推荐使用):在一个事务提交后就会更改数据库,数据库中 version 的值会自动加 1 。实现步骤 à 1 、在持久化类中加入 version 属性,生成其 getter setter 方法。 2 、在配置文件中的 <class> 标签中配置一个属性 optimistic-lock=”version” (这个属性的默认值就是 version ,可以不进行配置,但建议配置上) 3 、对 version 字段进行映射,使用 version 标签(这个字段的映射必须在 id 标签的后面第一位) à <version  name=”version”/>

细节分析 à 在一个事务加载某个持久化类时,对这个对象进行了一系列操作,但是还没有提交事务,于此同时,另外一个事物也加载了这个持久化类,并完成了一系列的操作后提交了事务,然后,第一个事务这时也要提交事务了,这样就会抛出一个异常 à org.hibernate.StableObjectStateException:Rows was updated or deleted by another transaction… ,原因是这样的:当一个事务提交时会发出这样一条 SQL 语句 à update 表名 set 所有表属性 =? where id( 唯一标示符值 )=? and version=? 这个语句中 version=? 是最关键的。以上说的那个例子中,第一个事务拿的是自己的旧的 version 值,进行更更新,而第二个事务在提交后,已经改变了 version ,变成了新的 version 值了,这样第一个事务提交事务时发出的 update 表名 set 所有表属性 =? where id( 唯一标示符值 ) =? and version=? 这条语句将会失败!就会抛出以上异常信息。

乐观锁:适合于高并发。

optimistic-lock 属性有如下可选取值:

  Ø none

无乐观锁

Ø version

通过版本机制实现乐观锁

Ø dirty

通过检查发生变动过的属性实现乐观锁

Ø all

通过检查所有属性实现乐观锁

2
1
分享到:
评论
1 楼 jack547155187 2012-03-28  
学习了。如果能再说明一下,在锁机制下操作失败后的采取处理策略就更好了

相关推荐

    Hibernate悲观锁和乐观锁的实现

    在进行Hibernate的测试时,可以创建一个名为`hibernate_test`的项目,编写对应的实体类、映射文件以及测试用例,模拟并发场景,来深入理解并对比悲观锁和乐观锁的差异和效果。 总之,理解并合理运用悲观锁和乐观锁...

    Hibernate锁机制_悲观锁和乐观锁

    Hibernate 中有两种锁机制:悲观锁和乐观锁。 一、悲观锁(Pessimistic Locking) 悲观锁是一种预防并发访问的机制,Hibernate 通过对数据库的锁定来实现。悲观锁假定任何时刻存取数据时,都可能有另一个客户也...

    Hibernate乐观锁和悲观锁分析

    主要分为两种类型:乐观锁(Optimistic Locking)和悲观锁(Pessimistic Locking)。 **悲观锁(Pessimistic Locking)** 悲观锁假设数据在任何时候都可能发生并发冲突,因此在数据读取时就对其进行锁定,确保在...

    Hibernate的乐观锁与悲观锁

    **Hibernate**作为一种流行的Java持久层框架,提供了多种机制来处理并发控制问题,其中最常用的就是**乐观锁**和**悲观锁**。本文将详细介绍这两种锁的原理、应用场景以及如何在Hibernate中实现。 #### 二、悲观锁...

    hibernate乐观锁和悲观锁学习

    本文主要讨论的是Hibernate框架中两种锁机制的使用:乐观锁和悲观锁。 首先,让我们深入理解悲观锁(Pessimistic Locking)。悲观锁正如其名字所示,假设并发环境中数据会被频繁修改,所以在整个数据处理过程中,它...

    hibernate的乐观锁和悲观锁

    ### Hibernate的乐观锁和悲观锁 #### 一、引言 在软件开发中,尤其是在涉及大量并发操作的应用场景下,确保数据的一致性和完整性是非常重要的。对于基于Java Web的应用而言,Hibernate作为一款流行的ORM框架,提供...

    Java 中的悲观锁和乐观锁的实现

    Hibernate中乐观锁的应用** 在Hibernate中,可以通过实体类中的版本字段来实现乐观锁。例如: ```java @Entity public class TUser { private int id; @Version private int version; // 版本号字段 // ...

    Hibernate.lock()方法中各种锁的区别.docx

    **悲观锁**(Pessimistic Lock)与**乐观锁**(Optimistic Lock)是数据库和对象关系映射(ORM)框架中两种重要的锁定机制,主要用于解决并发控制问题。 ##### 悲观锁 悲观锁假设数据会被频繁地并发访问和修改,...

    Hibernate教程26_事务并发处理

    本教程主要聚焦于Hibernate中的事务并发处理,包括悲观锁和乐观锁两种策略,这对于我们理解如何在高并发环境中确保数据的一致性和完整性至关重要。 首先,事务是数据库操作的基本单元,它确保一组操作要么全部成功...

    Web应用中并发控制的实现.pdf

    为了解决这些问题,通常会采用两种锁机制——乐观锁和悲观锁。 1. 乐观锁(Optimistic Locking)乐观锁假设并发冲突较少,因此在数据读取时不加锁,而在更新时检查数据是否已被其他事务修改。例如,Hibernate通过...

    JavaEE练习题(附答案).doc

    Hibernate 支持两种类型的锁来处理并发问题:悲观锁(pessimistic lock)和乐观锁(optimistic lock)。 #### 9. Struts2 的拦截器 Struts2 中可以使用 `&lt;s.token&gt;` 标签来解决重复提交问题,并使用 `&lt;s.text&gt;` ...

    criteria介绍与使用

    - **LockMode**:控制对实体加锁的方式,例如`Optimistic`或`Pessimistic`。 - **Criterion组合**:可以通过`Junction`类组合多个`Criterion`对象,实现更复杂的查询条件。 #### 实战应用 1. **使用Restrictions...

Global site tag (gtag.js) - Google Analytics