高并发问题是程序设计所必须要解决的问题,解决此类问题最主要的途径就是对对程序进行加锁控制。hibernate对加锁机制同样做出了实现,常用加锁方式为悲观锁和乐观锁。悲观锁指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态,通常是由数据库机制实现的,在整个过程中把数据锁住(查询时),只要事务不释放(提交或者回滚)任何用户都不能查看或修改。

悲观锁的应用:

悲观锁的应用十分的简单,如果使用get或load方法进行查询,只需要将load/get方法的第三个参数LockMode设置为UPGRADE就可以了,使用这个参数后我们每次发送的SQL语句都会加上"for update"用于告诉数据库锁定相关数据。如:         Inventory inv =(Inventory)session.load(Inventory.class, "1001", LockMode.UPGRADE);。如果直接使用hql语句的话,可以在语句的末尾加入for update,如:select s from Student s where s.name=”张三” for update,这条语句的末尾加入forupdate 后所有name为“张三”的数据都将会被锁定。

虽然悲观锁在Hibernate中应用十分容易,但在实际应用中使用悲观锁的情况并不多,因为它大大限制了程序的并发性,如果查询过程时间过长会给客户带来极其不好的体验。

乐观锁的应用:

其实与其说加锁不如说它更像是一种版本检测工具,其工作原理是这样的:需要在数据表中添加一个version字段,当读出数据的时候会将该字段的值一并读出,在进行更新操作的时候会将此版本号加一,然后对比新的版本号与数据库表中的版本号,如果新提交的版本号不大于数据表中的版本号则会被认为是过期数据不予更新,否则则进行数据更新。相对于悲观锁来讲乐观锁的加锁机制更加宽松,而且由于乐观锁是基于数据库表的版本解决方案,并不像悲观锁依靠于数据库的锁机制保证操作的最大独占性(会增加数据库的性能开销),所以乐观锁在实际中的应用要远远多于悲观锁。Hibernate对于乐观锁提供了三种实现,他们分别是:

1.      基于version

2.      基于timestamp

3.      基于遗留项目

其中前两种的原理是一样的,一个是以数字1,2,3…作为版本标识,而另一个是以时间作为版本标识而已,但应注意一顶要把version标签(或timestamp标签)放到id的下面而且要紧邻id。我们以version为例,在映射文件中做如下配置:

  1. <hibernate-mapping>
  2. <class name="com.bjpowernode.hibernate.Inventory" table="t_inventory" optimistic-lock="version" >
  3. <id name="itemNo">
  4. <generator class="assigned"/>
  5. </id>
  6. <version name="version"/>
  7. <!--<timestamp name="updateDate"/> -->
  8. <property name="itemName"/>
  9. <property name="quantity"/>
  10. </class>
  11. </hibernate-mapping>

如果要换成第二种,只要把映射文件中的version标签换成timestamp标签就可以了(当然需要在实体类中加入相应的成员变量)。

那什么又叫基于遗留项目的乐观锁呢?由于各种原因无法为原有的数据库添加"version"或"timestamp"字段,这时不可以使用上面方式配置乐观锁,Hibernate为这种情况提供了一个"optimisitic-lock"属性,它位于<class>标签上,同时必须设置optimistic-lock属性值为all并且设置dynamic-update属性值为true。设置了这种乐观锁与前两种相比不再是根据vsersion版本号或者时间戳的不同来判断是否是最新数据,而是根据表中所有字段来判断是否是最新数据,只要有任意一个字段的值发生了变化,就会被认为是过期数据不予提交。

它的配置文件是这样的:

  1. <hibernate-mapping>
  2. <class name="com.bjpowernode.hibernate.Inventory" table="t_inventory" optimistic-lock="all" dynamic-update="true">
  3. <id name="itemNo">
  4. <generator class="assigned"/>
  5. </id>
  6. <!-- <version name="version"/> -->
  7. <!--<timestamp name="updateDate"/> -->
  8. <property name="itemName"/>
  9. <property name="quantity"/>
  10. </class>
  11. </hibernate-mapping>

至此我们介绍完了Hibernate中悲观锁和乐观锁的实现,希望对大家进一步理解乐观锁和悲观锁有所帮助。

Hibernate解决高并发问题之:悲观锁 VS 乐观锁的更多相关文章

  1. 使用数据库乐观锁解决高并发秒杀问题,以及如何模拟高并发的场景,CyclicBarrier和CountDownLatch类的用法

    数据库:mysql 数据库的乐观锁:一般通过数据表加version来实现,相对于悲观锁的话,更能省数据库性能,废话不多说,直接看代码 第一步: 建立数据库表: CREATE TABLE `skill_ ...

  2. 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存

    原文:http://blog.csdn.net/heyewu4107/article/details/71009712 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存 问 ...

  3. PHP利用Mysql锁解决高并发

    前面写过利用文件锁来处理高并发的问题的,现在我们说另外一个处理方式,利用Mysql的锁来解决高并发的问题 先看没有利用事务的时候并发的后果 创建库存管理表 CREATE TABLE `storage` ...

  4. 利用redis实现分布式事务锁,解决高并发环境下库存扣减

    利用redis实现分布式事务锁,解决高并发环境下库存扣减   问题描述: 某电商平台,首发一款新品手机,每人限购2台,预计会有10W的并发,在该情况下,如果扣减库存,保证不会超卖 解决方案一 利用数据 ...

  5. java解决高并发问题

    对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...

  6. 025 hibernate悲观锁、乐观锁

    Hibernate谈到悲观锁.乐观锁,就要谈到数据库的并发问题,数据库的隔离级别越高它的并发性就越差 并发性:当前系统进行了序列化后,当前读取数据后,别人查询不了,看不了.称为并发性不好 数据库隔离级 ...

  7. Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS

    首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁.传统的关系型数据库里边就用到了很 ...

  8. Hibernate 再接触 悲观锁和乐观锁

    为什么取1248 二进制 CRUD 移位效率高 在并发和效率选择一个平衡点 一般不会考虑幻读 因为我们不会再一个事务里查询两次,(只能设置为seralizable) 悲观锁和乐观锁的前提是read-u ...

  9. 转发:php解决高并发

    php解决高并发(转发:https://www.cnblogs.com/walblog/articles/8476579.html) 我们通常衡量一个Web系统的吞吐率的指标是QPS(Query Pe ...

随机推荐

  1. Huawei HG556a A版 刷 openwrt

    一直想玩玩openwrt,调研了一下 HG556a尽管散热很烂,但性价比超高,于是淘宝入手一台A版,A版和C版区别为wifi芯片: 到货后在网上找了几个教程便开始动手刷openwrt,但刷机的过程中还 ...

  2. Mysql 配置主从服务自动同步功能

    1.修改主服务器master:   #vi /etc/my.cnf       [mysqld]       log-bin=mysql-bin   //[必须]启用二进制日志       serve ...

  3. WPF容器控件

    WPF有五种容器控件,分别为Grid,Canvas,StackPanel,WrapPanel,DockPanel. Grid: 1.Height=”60”:不加“星号”表示固定的高度 2.Height ...

  4. easy ui datagrid 设置冻结列

    为了冻结列,您需要定义 frozenColumns 属性.frozenColumn 属性和 columns 属性一样. $('#tt').datagrid({ title:'Frozen Column ...

  5. 【BZOJ 1927】 [Sdoi2010]星际竞速

    Description 10 年一度的银河系赛车大赛又要开始了.作为全银河最盛大的活动之一, 夺得这个项目的冠军无疑是很多人的梦想,来自杰森座 α星的悠悠也是其中之一. 赛车大赛的赛场由 N 颗行星和 ...

  6. 1199: [HNOI2005]汤姆的游戏 - BZOJ

    Description 汤姆是个好动的孩子,今天他突然对圆规和直尺来了兴趣.于是他开始在一张很大很大的白纸上画很多很多的矩形和圆.画着画着,一不小心将他的爆米花弄撒了,于是白纸上就多了好多好多的爆米花 ...

  7. JSP页面用EL表达式 输出date格式

    JSP页面用EL表达式 输出date格式 1.头上引入标签 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix ...

  8. HTML5 中的块级链接

    英文叫做 “Block-level” links,我以为只有我厂那些鸟毛不知道,没想到不知道的还挺多, 需要普及一下. 最近看了 kejun 的 PPT 前端开发理论热点面对面:从怎么看,到怎么做?, ...

  9. php站点

    thinkphp wordpress 记事狗 phpcms http://jingyan.baidu.com/article/4b07be3c61e93e48b380f3fd.html

  10. 【BZOJ 2829】 2829: 信用卡凸包 (凸包)

    2829: 信用卡凸包 Description Input Output Sample Input 2 6.0 2.0 0.0 0.0 0.0 0.0 2.0 -2.0 1.5707963268 Sa ...