Hibernate的悲观锁和乐观锁
前一篇博客我们从数据库角度分析,锁可以分为三种,分别为共享锁,独占锁和更新锁。我们从程序的角度来看锁可以分为两种类型,悲观锁和乐观锁,Hibernate提供对这两种锁 的支持,我们来了解一下Hibernate如何实现这两种锁。
一、悲观锁 Pessimistic Locking
通常由数据库机制实现,在查询的整个过程中把数据锁住,只要事务不释放(提交/回滚),那么其他任何用户都不能查看或修改数据,这种锁的方式是比较简单、直接。从开始就讲数据全部锁上,这种锁主要针对并发修改造成数据不一致的问题,但同时也会造成死锁的发生。
适用场景:适合短事务
示例:两个用户同时去到同一个数据100,用户1先将数据减20,这时数据库里的是80,用户2刚才读取到的是100,现在用户2,这样就会造成数据混乱。采用锁的方式解决这种问题。
悲观锁:在用户1读取数据的时候,用锁将数据锁上,而用户2读取不到数据,只要用户1将数据修改后并提交,才释放锁,此时用户2才能读取到数据,而这时候读取到的是用户1修改后的数据,也就解决了数据混乱的问题了。
实体类:
public class Inventory {
private String itemNo;
private String itemName;
private int quantity;
public void setItemNo(String itemNo) {
this.itemNo = itemNo;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
配置文件:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Inventory" table="t_inventory">
<id name="itemNo">
<generator class="assigned"/>
</id>
<property name="itemName"/>
<property name="quantity"/> </class> </hibernate-mapping>
LockModel(使用UPGRADE)
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----ItemNname ="+inv.getItemName());
System.out.println("opt1----Quantity ="+inv.getQuantity());
session.beginTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
二、乐观锁OptimisticLocking
不是锁,是一种冲突检测机制,乐观锁的并发性要好于悲观锁。常用的方式可以使用数据版本的方式(version)实现,一般是在数据库中加入一个version字段,在读取数据的时候将version字段读取出来,在保存数据的时候判断version的值是否小于数据库中version的版本,如果小于不予更新,否则更新数据。
实体类:
在实体类配置中添加上版本的映射
public class Inventory {
private String itemNo;
private String itemName;
private int quantity;
private int version;
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public String getItemNo() {
return itemNo;
}
public void setItemNo(String itemNo) {
this.itemNo = itemNo;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
配置文件:
<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>
使用方式还是和之前的一样,这样在更新之前就会跟数据库中版本对比,能够更好的解决数据混乱的问题。
总结:
数据库添加锁的两种方式,悲观锁简单明了,它将一切都以悲观的眼光来看待,认为一切都是并发的,而且当数据库很大或者遇到问题就很容易造成死锁。乐观锁的方式更加和谐,能够更好的处理并发问题。
Hibernate的悲观锁和乐观锁的更多相关文章
- Hibernate解决高并发问题之:悲观锁 VS 乐观锁
高并发问题是程序设计所必须要解决的问题,解决此类问题最主要的途径就是对对程序进行加锁控制.hibernate对加锁机制同样做出了实现,常用加锁方式为悲观锁和乐观锁.悲观锁指的是对数据被外界(包括本系统 ...
- 025 hibernate悲观锁、乐观锁
Hibernate谈到悲观锁.乐观锁,就要谈到数据库的并发问题,数据库的隔离级别越高它的并发性就越差 并发性:当前系统进行了序列化后,当前读取数据后,别人查询不了,看不了.称为并发性不好 数据库隔离级 ...
- Hibernate 再接触 悲观锁和乐观锁
为什么取1248 二进制 CRUD 移位效率高 在并发和效率选择一个平衡点 一般不会考虑幻读 因为我们不会再一个事务里查询两次,(只能设置为seralizable) 悲观锁和乐观锁的前提是read-u ...
- mysql-mysql悲观锁和乐观锁
1.mysql的四种事务隔离级别 I. 对于同时运行多个事务,当这些事务访问数据库中的相同数据时,如果没有采取必要的隔离机制,就会导致各种并发问题. (1)脏读: 对于两个事物 T1, T2, T1 ...
- Oracle数据库悲观锁与乐观锁详解
数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住.而乐 ...
- MySQL学习笔记(四)悲观锁与乐观锁
恼骚 最近在搞并发的问题,订单的异步通知和主动查询会存在并发的问题,用到了Mysql数据库的 for update 锁 在TP5直接通过lock(true),用于数据库的锁机制 Db::name('p ...
- 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?
在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...
- Oracle的悲观锁和乐观锁
为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突.为了解决这个问题,大多数数据库用的方法就是数据的锁定. 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫 ...
- (转载)Oracle的悲观锁和乐观锁
为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突.为了解决这个问题,大多数数据库用的方法就是数据的锁定. 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫 ...
随机推荐
- Modelsim SE-64 10.4的安装 、破解以及远程使用
1.准备好modelsim SE-64 10.4的安装包和破解文件(modelsim-win64-10.4-se.exe 和MentorKG.exe ,patch_dll.bat). 2.安装 好 ...
- tp3.2 如何比较两个字段
使用exp if ($_GET['owe_property'] || $_GET['owe_property'] !== NULL) { if ((int)$_GET['owe_property'] ...
- (语法基础)浅谈面向切面编程(AOP)
一:前言 面向切面编程是一个很重要的编程思想,想要写出一个便于维护的程序,理解AOP并且能熟练的在实际编程中合理的运用AOP思想是很有必要的 二:AOP的基本概念 基础概念:AOP中文翻译面向切面编程 ...
- 22 Oracle数据库基础入门
1.Oracle数据库的介绍 ORACLE 数据库系统是美国ORACLE 公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或 B/S 体 ...
- Java开发笔记(一百四十六)JDBC的应用原理
关系数据库使得海量信息的管理成为现实,但各家数据库提供的编程接口不尽相同,就连SQL语法也有所差异,像Oracle.MySQL.SQL Server都拥有自己的开发规则,倘若Java针对每个数据库单独 ...
- 用Scratch制作一个Hello World程序
网上出现了很多Hello World程序,看的小编心里也痒痒的,为此这次作为南京小码王Scratch培训机构的小编,就为大家来详细的了解下Scratch制作Hello World程序的过程,现在就和小 ...
- 虚拟机CentOS创建/使用快照
快照 1.什么是快照 说的直白一点,就是创建一个备份.当执行了不可逆的错误操作后,可以通过快照用来恢复系统 2.创建快照的三种模式 挂载状态下创建快照 开机状态下创建快照 关机状态下创建快照 3.如何 ...
- 【LEETCODE】60、数组分类,适中级别,题目:75、560、105
package y2019.Algorithm.array.medium; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.a ...
- vue路由懒加载及组件懒加载
一.为什么要使用路由懒加载 为给客户更好的客户体验,首屏组件加载速度更快一些,解决白屏问题. 二.定义 懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载. 三.使用 常用的懒加载方式 ...
- 简单端口映射、转发、重定向工具-Rinetd
一.简介 Rinetd是为在一个Unix和Linux操作系统中为重定向传输控制协议(TCP)连接的一个工具.Rinetd是单一过程的服务器,它处理任何数量的连接到在配置文件etc/rinetd中指定的 ...