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的悲观锁和乐观锁
为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突.为了解决这个问题,大多数数据库用的方法就是数据的锁定. 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫 ...
随机推荐
- Kubernetes 使用 Weave Scope 监控集群(十七)
目录 一.安装 二.使用 Scope 2.1.拓扑结构 2.2.在线操作 2.3.强大的搜索功能 创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所 ...
- Node.js实现PC端类微信聊天软件(三)
Github StackChat Redux学习回顾 Redux的主要功能就是管理复杂交错的State,比如需要讲state提升到顶层组件的场景中,使用Redux就很合适 Redux主要提供三个东西来 ...
- Oracle Spatial分区应用研究之七:同等分区粒度下全局索引优于分区索引的原因分析
1.实验结论 同等分区粒度下,使用分区空间索引进行空间查询,比使用全局空间索引进行查询,对数据字典表的访问次数更多.假设分区数为X,则大概多3X次访问.具体说明见6实验结论. 2.实验目的 在之前的测 ...
- 移动端1px边框解决方案
在retina屏中,像素比为2(iPhone6/7/8)或3(iPhone6Plus/7Plus/8Plus),1px的边框看起来比真的1px更宽. 使用伪类加transform的方式 元素本身不定义 ...
- SQL Server 中关于系统库Tempdb总结
Tempdb系统数据库是一个全局资源,可供连接到SQL Server实例的所有用户使用. 存储的内容项: 1.用户对象 用户对象由用户显示创建.这些对象可以位于用户会话的作用域中,也可以位于创建对象所 ...
- 在JDBC中实现SQL语句的模糊查询
在JDBC中实现SQL语句的模糊查询 在大多数情况下我们可以在JDBC中写入sql语句通过占位符的方式来直接查询,但是如果要进行模糊查询,需要转义字符才能够正常查询. sql语句: select * ...
- Java开发笔记(一百四十七)通过JDBC管理数据库
前面介绍了如何通过JDBC获取数据库连接,可是Connection对象不能直接执行SQL语句,需要引入Statement报告对象才能操作SQL.Statement对象由Connection的creat ...
- Java多线程编程(4)--线程同步机制
一.锁 1.锁的概念 线程安全问题的产生是因为多个线程并发访问共享数据造成的,如果能将多个线程对共享数据的并发访问改为串行访问,即一个共享数据同一时刻只能被一个线程访问,就可以避免线程安全问题.锁 ...
- 重置 Macbook 登录密码
1.按 开机键 的同时 按 Command + R,等进度条走完,会出现如下图 2.在菜单栏,选取“实用工具”>“终端”. 3.在终端窗口,键入下面的命令:resetpassword 按下回车键 ...
- python笔记:删除列表元素和根据索引查找元素
查找元素 #查找元素 >>> member=['张三','李四','王五','张麻子'] >>> member[0] '张三' #交换元素 >>> ...