Hibernate解决高并发问题之:悲观锁 VS 乐观锁
高并发问题是程序设计所必须要解决的问题,解决此类问题最主要的途径就是对对程序进行加锁控制。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为例,在映射文件中做如下配置:
- <hibernate-mapping>
- <class name="com.bjpowernode.hibernate.Inventory" table="t_inventory" optimistic-lock="version" >
- <id name="itemNo">
- <generator class="assigned"/>
- </id>
- <version name="version"/>
- <!--<timestamp name="updateDate"/> -->
- <property name="itemName"/>
- <property name="quantity"/>
- </class>
- </hibernate-mapping>
如果要换成第二种,只要把映射文件中的version标签换成timestamp标签就可以了(当然需要在实体类中加入相应的成员变量)。
那什么又叫基于遗留项目的乐观锁呢?由于各种原因无法为原有的数据库添加"version"或"timestamp"字段,这时不可以使用上面方式配置乐观锁,Hibernate为这种情况提供了一个"optimisitic-lock"属性,它位于<class>标签上,同时必须设置optimistic-lock属性值为all并且设置dynamic-update属性值为true。设置了这种乐观锁与前两种相比不再是根据vsersion版本号或者时间戳的不同来判断是否是最新数据,而是根据表中所有字段来判断是否是最新数据,只要有任意一个字段的值发生了变化,就会被认为是过期数据不予提交。
它的配置文件是这样的:
- <hibernate-mapping>
- <class name="com.bjpowernode.hibernate.Inventory" table="t_inventory" optimistic-lock="all" dynamic-update="true">
- <id name="itemNo">
- <generator class="assigned"/>
- </id>
- <!-- <version name="version"/> -->
- <!--<timestamp name="updateDate"/> -->
- <property name="itemName"/>
- <property name="quantity"/>
- </class>
- </hibernate-mapping>
至此我们介绍完了Hibernate中悲观锁和乐观锁的实现,希望对大家进一步理解乐观锁和悲观锁有所帮助。
Hibernate解决高并发问题之:悲观锁 VS 乐观锁的更多相关文章
- 使用数据库乐观锁解决高并发秒杀问题,以及如何模拟高并发的场景,CyclicBarrier和CountDownLatch类的用法
数据库:mysql 数据库的乐观锁:一般通过数据表加version来实现,相对于悲观锁的话,更能省数据库性能,废话不多说,直接看代码 第一步: 建立数据库表: CREATE TABLE `skill_ ...
- 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存
原文:http://blog.csdn.net/heyewu4107/article/details/71009712 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存 问 ...
- PHP利用Mysql锁解决高并发
前面写过利用文件锁来处理高并发的问题的,现在我们说另外一个处理方式,利用Mysql的锁来解决高并发的问题 先看没有利用事务的时候并发的后果 创建库存管理表 CREATE TABLE `storage` ...
- 利用redis实现分布式事务锁,解决高并发环境下库存扣减
利用redis实现分布式事务锁,解决高并发环境下库存扣减 问题描述: 某电商平台,首发一款新品手机,每人限购2台,预计会有10W的并发,在该情况下,如果扣减库存,保证不会超卖 解决方案一 利用数据 ...
- java解决高并发问题
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...
- 025 hibernate悲观锁、乐观锁
Hibernate谈到悲观锁.乐观锁,就要谈到数据库的并发问题,数据库的隔离级别越高它的并发性就越差 并发性:当前系统进行了序列化后,当前读取数据后,别人查询不了,看不了.称为并发性不好 数据库隔离级 ...
- Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS
首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁.传统的关系型数据库里边就用到了很 ...
- Hibernate 再接触 悲观锁和乐观锁
为什么取1248 二进制 CRUD 移位效率高 在并发和效率选择一个平衡点 一般不会考虑幻读 因为我们不会再一个事务里查询两次,(只能设置为seralizable) 悲观锁和乐观锁的前提是read-u ...
- 转发:php解决高并发
php解决高并发(转发:https://www.cnblogs.com/walblog/articles/8476579.html) 我们通常衡量一个Web系统的吞吐率的指标是QPS(Query Pe ...
随机推荐
- ubuntu下安装ffmpeg和X264
第一步:安装必要的库 $:-dev libtheora-dev libx11-dev zlib1g-dev 第二步:安装SDL(否则可能编译不出ffplay) $:-dev $:-dev libsdl ...
- 浅谈string
#include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件 using std::string;using ...
- Oracle的Import用法
1. imp 命令介绍 imp 命令可以通过输入各种参数来控制导出方式: imp keyword=value 或 keyword=(value1,value2,...,valueN) ,例如 i ...
- MDI-多文档窗体
1.IsMdicontainer属性设置是否为多文档窗体 this.IsMdiContainer = true; 2.MdiParent属性设置为父窗体 Frm_Child frm = new Frm ...
- There is a legend about a bird
There is a legend about a bird which sings just once in its life, more sweetly than any other ...
- [ 转载]JAVA Socket超时浅析
JAVA Socket超时浅析 转载自 http://blog.csdn.net/sureyonder/article/details/5633647 套接字或插座(socket)是一种软件形 式的抽 ...
- linux 常用命令 集锦
第一章 LINUX简介及安装 1一.LINUX介绍 1二.LINUX安装 2三.LINUX目录 2四.总结来说: 3第二章 常用命令及帐户管理 4一.linux命 ...
- spring的三种注解管理器
1.依赖注入的注解解析器 在配置文件中; * xsd xmlns:context="http://www.springframework.org/schema/context" h ...
- 1874: [BeiJing2009 WinterCamp]取石子游戏 - BZOJ
Description小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问 ...
- API HOOK
API HOOK技术是一种用于改变API执行结果的技术,Microsoft 自身也在Windows操作系统里面使用了这个技术,如Windows兼容模式等. API HOOK 技术并不是计算机病毒专有技 ...