`

快速掌握Hibernate中悲观锁和乐观锁(转)

    博客分类:
  • SSH
阅读更多

我们在使用Hibernate中经常用到当多个人对同一数据同时进行修改的时候,会发生脏数据,造成数据的不一致性,解决办法是可以通过悲观锁和乐观锁来实现。

Hibernate悲观锁:在数据有加载的时候就给其进行加锁,直到该锁被释放掉,其他用户才可以进行修改,优点:数据的一致性保持得很好,缺点:不适合多个用户并发访问。当一个锁住的资源不被释放掉的时候,这个资源永远不会被其他用户进行修改,容易造成无限期的等待。

Hibernate乐观锁:就是在对数据进行修改的时候,对数据才去版本或者时间戳等方式来比较,数据是否一致性来实现加锁。优点比较好。

一、在Hibernate悲观锁中,只要在加载的时候,才去session中的load方法,进行枷锁,session.load(****.class,1,LockMode.UPDATE);

Hibernate将事务管理委托给底层的JDBC或者JTA,默认是基于JDBC Transaction的。Hibernate支持“悲观锁(Pessimistic Locking)”和“乐观锁(Optimistic Locking)”。
Hibernate悲观锁对数据被外界修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。Hibernate悲观锁的实现,往往依靠数据库提供的锁机制。Hibernate通过使用数据库的for update子句实现了悲观锁机制。

Hibernate的加锁模式有:

1. LockMode.NONE:无锁机制

2. LockMode.WRITE:Hibernate在Insert和Update记录的时候会自动获取

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

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

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


二、乐观锁大多是基于数据版本(Version)记录机制实现。Hibernate在其数据访问引擎中内置了Hibernate乐观锁实现,可以通过class描述符的optimistic-lock属性结合version描述符指定。optimistic-lock属性有如下可选取值:


1. none:无乐观锁

2. version:通过版本机制实现乐观锁

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

4. all:通过检查所有属性实现乐观锁

例子:
1)Hibernate悲观锁:

1>POJO类
public class PersimisticLocking { 
 private int id; 
  
 private String Item; 
  
 private int price; 
//省略setter、getter方法 
}

2>、POJO类的映射文件
 <?xml version="1.0"?>
 <!DOCTYPE hibernate-mapping PUBLIC  
     "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 <hibernate-mapping package="org.apple.hibernate">
     <class name="PersimisticLocking" table="t_persimisticLocking">
         <id name="id">
             <generator class="native"/>
         </id>
        <property name="item"/>
        <property name="price"/>
    </class>
</hibernate-mapping>

3>、加载测试方法
public void testLoad1() 
     { 
         Session session = null; 
         try { 
             session = HibernateUtil.getSession(); 
             session.beginTransaction(); 
             OptimisticLocking o = (OptimisticLocking)session.load(OptimisticLocking.class, 1); 
             System.out.println("o.item="+o.getItem()); 
             System.out.println("o.price="+o.getPrice()); 
            System.out.println("o.version="+o.getVersion()); 
            o.setPrice(o.getPrice()-10); 
            session.update(o); 
            session.beginTransaction().commit(); 
        } catch (Exception e) { 
            // TODO: handle exception 
            e.printStackTrace(); 
            session.beginTransaction().rollback(); 
        }finally{ 
            HibernateUtil.closeSession(session); 
        } 
         
    }

可以设置另外类似的方法,不枷锁,先对上面的测试代码设置断点,点debug一部分,再运行不枷锁的,可以看到,如果上面方法不释放锁的话,下面的数据就会造成无限期的等待。

2、Hibernate乐观锁:

1>在悲观锁的基础上加入private int version;和相关的setter、getter方法。

2>映射文件配置在class标签里面加入optimistic-lock="version",然后在的id标签后面加入<version name="version"/>

3>测试方法:
public void testLoad1() 
     { 
         Session session = null; 
         try { 
             session = HibernateUtil.getSession(); 
             session.beginTransaction(); 
             OptimisticLocking o = (OptimisticLocking)session.load(OptimisticLocking.class, 1); 
             System.out.println("o.item="+o.getItem()); 
             System.out.println("o.price="+o.getPrice()); 
            System.out.println("o.version="+o.getVersion()); 
            o.setPrice(o.getPrice()-10); 
            session.update(o); 
            session.beginTransaction().commit(); 
        } catch (Exception e) { 
            // TODO: handle exception 
            e.printStackTrace(); 
            session.beginTransaction().rollback(); 
        }finally{ 
            HibernateUtil.closeSession(session); 
        } 
         
    }

在初始数据的时候,version为0,在没更新一次version都会在原来的基础上加1,通过version的版本来实现Hibernate乐观锁。

在上面的测试方法里面复制成另外一个方法,对上面的方法进行设置断点,然后单步调试几部,到NO.11行的时候暂停,此时对复制的另外方法运行,然后再运行完上面的方法,就会抛出异常,所以,在实际的项目开发中,可以通过对异常进行出来,这样就会实现并发访问。

分享到:
评论

相关推荐

    hibernate中文参考文档

    7. **事务和并发控制**:讲述了如何在Hibernate中处理事务,以及乐观锁、悲观锁等并发控制策略。 8. **事件和监听器**:讨论了在特定操作前后执行自定义逻辑的事件模型。 9. **性能优化**:提供了优化Hibernate...

    hibernate经典教材从入门到精通(共四篇)

    此外,事务管理和并发控制也是重要的内容,如乐观锁和悲观锁的概念及其在Hibernate中的应用。 第四篇通常会涵盖一些实战和最佳实践,如性能优化技巧,如何减少数据库访问次数、提高查询效率,以及如何避免常见的...

    hibernate3 帮助文档CHM

    13. **其他高级特性**:如级联操作、联合主键、复合主键、外键约束、乐观锁和悲观锁等。 综上所述,《Hibernate3 帮助文档 CHM》是Java开发者不可或缺的参考资料,无论你是初学者还是经验丰富的开发者,都可以从中...

    深入浅出Hibernate完整版

    事务管理是任何数据库操作中不可或缺的一部分,文档不仅阐述了基于JDBC和JTA的事务管理策略,还深入分析了悲观锁和乐观锁的原理,帮助读者掌握如何在并发环境下正确地管理数据的一致性和完整性。 #### 分页与缓存...

    孙卫琴 精通hibernate源码上

    7. **Chapter 8**:可能涉及到事务管理和并发控制,包括Hibernate对JTA(Java Transaction API)的支持,以及乐观锁和悲观锁的概念及其在实际开发中的应用。 8. **Appendix A, B, C**:附录通常用来补充正文中的...

    夏昕-Hibernate+开发指南.pdf

    - **定位区别**:不同于Hibernate官方参考文档(Hibernate Reference),本文档旨在为开发者提供一个学习和掌握Hibernate的路径,而非简单的条目索引。 #### 二、文档结构与内容 - **文档版本**:本文档为V1.0版本...

    Hibernate开发指南

    此外,还讲解了悲观锁和乐观锁的使用,这两者用于处理并发访问时数据的一致性问题。 Hibernate分页功能允许开发者在查询时分批次加载数据,这对于操作大量数据的场景非常有用。Cache管理部分介绍了Hibernate的二级...

    Hibernate开发指南(原版书)

    - **事务管理**:分析基于JDBC和JTA的事务管理机制,比较它们的特点和适用场景,同时介绍锁(locking)的概念,包括悲观锁和乐观锁的不同之处及其在并发控制中的作用。 - **Hibernate分页**:展示如何利用Hibernate...

    Hibernate3.2.chm

    同时,也会涉及并发控制,如乐观锁(@Version)和悲观锁的应用。 查询是数据操作的重要部分,手册将详细解释HQL(Hibernate Query Language),它是Hibernate提供的面向对象的查询语言,类似于SQL。除此之外,还会...

    Hibernate学习精粹

    本书旨在帮助读者快速掌握Hibernate的核心概念和技术细节,提高开发效率。 #### 二、准备工作 在开始使用Hibernate之前,需要做一些准备工作,确保环境配置正确。具体步骤如下: 1. **下载Ant**:首先下载Apache ...

    hibernate 操作视频

    【hibernate 操作视频】教程是一系列详细讲解Hibernate框架使用的教学资源,旨在帮助初学者快速掌握这个强大的Java持久化框架。Hibernate是一个对象关系映射(ORM)工具,它简化了数据库与Java对象之间的交互,使得...

    Hibernate开发指南.pdf

    5. **锁机制**:Hibernate支持两种类型的锁机制:悲观锁和乐观锁,它们分别用于解决并发问题的不同场景。 6. **分页**:当查询结果集较大时,可以使用分页技术来提高性能。 7. **缓存管理**:Hibernate支持一级...

    Hibernate中文教程

    - 主要涉及乐观锁和悲观锁的选择与实现。 - 解决方案:根据应用场景选择合适的锁机制,并合理配置Hibernate的相关参数。 #### 七、总结 通过本教程的学习,读者能够深入了解Hibernate的工作原理和使用方法,掌握...

    hibernate参考手册

    重点介绍了乐观并发控制和悲观锁的概念,以及它们在多用户环境下如何确保数据一致性。这部分内容对于构建高性能、高可用性的企业级应用至关重要。 五、拦截器与事件系统 介绍Hibernate的事件机制,包括如何注册和...

Global site tag (gtag.js) - Google Analytics