【Hibernate】——悲观锁和乐观锁

来源:互联网 发布:抽数字软件在线 编辑:程序博客网 时间:2024/05/29 10:25

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

悲观锁

              悲观锁通常是由数据库机制实现的,在整个过程中把数据锁住(查询时),只要事务不释放(提交/回滚),那么任何用户都不能查看或修改。否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据。

              锁主要是解决并发性问题,如更新丢失,就是在不知情的情况下自己改的东西被莫名的覆盖了。


Hibernate的加锁模式

              LockMode.NONE无锁机制。 

              LockMode.WRITEHibernateInsertUpdate记录的时候会自动获取。 

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

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

              LockMode.UPGRADE_NOWAITOracle的特定实现,利用Oraclefor update nowait子句实现加锁。

              前三种锁机制一般由Hibernate内部使用,如Hibernate为了保证Update 过程中对象不会被外界修改,会在save方法实现中自动为目标对象加上WRITE锁。

          

hibernate是如何支持悲观锁的?

              悲观锁在加载的时候就要锁住。

public void testLoad1(){Session session=null;try{session=HibernateUtils.getSession();session.beginTransaction();Inventory inv=(Inventory)session.load(Inventory.class,"1001", LockMode.UPGRADE);System.out.println("opt1-->itemNo="+inv.getItemNo());System.out.println("opt1-->itemName="+inv.getItemNo());System.out.println("opt1-->quantty="+inv.getQuantity());inv.setQuantity(inv.getQuantity()-200);session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);}}

              虽然悲观锁解决了更新丢失的问题,但是也会带来新的问题。因为悲观锁只有在提交事务之后才会被释放,但是假设这个事务周期特别长,执行了好多代码花了很长时间之后才提交事务,那么别人谁也动不了了,这就会导致别人一直处于一种等待的状态。悲观锁是一种独占锁。同时它也影响并发性,所以用什么锁要看具体情况。

 

乐观锁

              之前悲观锁遇到的问题,如果有一些应用是高并发的,我们可以用乐观锁。但是乐观锁不是锁,是一种冲突检测的手段。

 

hibernate是如何支持乐观锁的?

               Hibernate中大多数的使用是采用数据版本的方式(version)实现,一般在数据库中加入一个version字段,它其实起到一个版本号的作用,也就是说旧版本不能更新新版本。在读取数据的时候将version读取出来,在保存数据的时候判断version的值是否小于数据库中的version值,如果小于不予更新,否则再给与更新。也就是在更新的时候会有一个冲突检测,如果不是最新版本会有报错或者提示等。

              当然利用时间戳也是这种原理的一种方式。

              version是由hibernate来维护的,所以需要使用特殊字段。

<hibernate-mapping><class name="com.bjpowernode.hibernate.Inventory" table="t_inventory" optimistic-lock="version"><id name="itemNo"><generator class="assigned"/></id><version name="version"/><property name="itemName"/><property name="quantity"/></class></hibernate-mapping>

总结

              悲观锁在遇到高并发的时候会出现延迟的现象,所以用什么锁要看具体情况而定。乐观锁就适合于高并发的情况。但它实质上是一种冲突检测。想版本控制工具CVS使用的就是乐观锁,而微软的VSS是悲观锁。


0 0