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 ...
随机推荐
- Pandas简易入门(四)
本节主要介绍一下Pandas的另一个数据结构:DataFrame,本文的内容来源:https://www.dataquest.io/mission/147/pandas-internals-dataf ...
- NodeJs环境部署
node cli.js install npm -gf npm install express -gd
- (转)Qt Model/View 学习笔记 (一)——Qt Model/View模式简介
Qt Model/View模式简介 Qt 4推出了一组新的item view类,它们使用model/view结构来管理数据与表示层的关系.这种结构带来的 功能上的分离给了开发人员更大的弹性来定制数据项 ...
- MINA快速传输文件
最近的项目使用MNA进行文件传输,只能传输到5~7MB/s:但是使用FTP等软件其实可以达到11MB/s,后来使用MINA原生传输,发现可以达到11MB/s,后来发现有以下两点可以需要注意优化: 1. ...
- 使用Schtasks命令的注意事项
在使用Schtasks命令时遇到了两个棘手的问题,耗费了一点时间,出现这个问题的时候查找网络资源也找不到真正的解决方案,最后还是自己悟出来了原因,所以在此把这些问题记录下来.如下: 服务器环境:win ...
- iOS的layoutSubviews和drawRect方法何时调用
layoutSubviews在以下情况下会被调用: 1.init初始化不会触发layoutSubviews.2.addSubview会触发layoutSubviews.3.设置view的Frame会触 ...
- 【leetcode】Container With Most Water(middle)
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). ...
- [杂题]FZU2190 非提的救赎
中文题,题意不多说. 本来感觉很像dp 其实只要从上到下维护单调性就好了 坑是......这个oj......用cin很容易TLE...... //#include <bits/stdc++.h ...
- PHP的执行原理/执行流程
http://www.cnblogs.com/hongfei/archive/2012/06/12/2547119.html 更深入的学习和了解可以查看下面: 风雨的博客http://www.laru ...
- 首次接触Winform前端交互
首次接触到在winform中加入网页,且跟前端脚本交互.找了一下这方面的资料 此博文转载原地址为:http://www.cnblogs.com/Charles2008/archive/2009/08/ ...