Hibernate学习---第十二节:Hibernate之锁机制&乐观锁实现
1、悲观锁
它指的是对数据被外界修改保持保守态度,因些,在整个数据处理过程中,将数据牌锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层的锁机制才能保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
一个典型的悲观锁调用示例:
select * from account where name = "12345" for update
通过for update子句,这条SQL锁定了account表中所有符合检索条件的记录。本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。
2、乐观锁
相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制,以操作最大程度的独占性。但随着而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。
乐观锁,大多是基于数据版本(Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于库表的版本解决方案中,一般是通过为数据库表增加version字段来实现。
读取出数据时,将此版本号一同读出,之生更新时,对此版本号加1.此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。
例如,两个人同时在同一个帐号取钱,账号有100,A取50,B取20,A先提交,B的余额即为80,这时就不同步了,A提交后版本已经变了2了,而B看到的还是1的版本,此时B的提交必须被驳回。
需要注意的是,乐观锁机制往往基于系统中的数据存储逻辑,因此也具备一定的局限性。如有些例子,由于乐观锁机制是在我们的系统中实现,来自外部系统的用户余额更新操作不受我们系统控制,因此可能会造成非法数据被更新到数据库中。
在系统设计阶段,我们应该充分考虑到某些情况出现的可能性,并进行相应调整(如将乐观锁策略在数据库存储过程中实现,对外只开放基于此存储过程的数据更新途径,而不是将数据库表直接对外公开)。
Hibernate 在其数据访问引擎中内置了乐观锁实现。如果不用考虑外部系统对数据库的更新操作,利用Hibernate提供的透明化乐观锁实现,将大大提升我们的生产力。
(1)、实体类
package learn.hibernate.bean; import java.util.Date;
import java.util.HashSet;
import java.util.Set; /**
* 持久化类设计
* 注意:
* 持久化类通常建议要有一个持久化标识符(ID)
* 持久化标识符通常建议使用封装类(例如:Integer 因为基本类型存在默认值)
* 持久化类通常建议手动添加一个无参构造函数 (因为有些操作是通过放射机制进行的)
* 属性通常建议提供 getter/setter 方法
* 持久化类不能使用 final 修饰
* 持久化类中如果使用了集合类型数据,只能使用集合所对应的接口类型来声明(List/Map/Set)
* 如下:ArrayList list = new ArrayList(); 不行
* List list = new ArrayList(); 可行
*/
public class Person { private Integer id;
private String name;
private int age;
private int passwork;
private Date birthday;
private Integer version; public Person() { } public Person(String name, int age, int passwork, Date birthday) {
super();
this.name = name;
this.age = age;
this.passwork = passwork;
this.birthday = birthday;
} @Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age
+ ", passwork=" + passwork + ", birthday=" + birthday + "]";
} public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getPasswork() {
return passwork;
}
public void setPasswork(int passwork) {
this.passwork = passwork;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
} public Integer getVersion() {
return version;
} public void setVersion(Integer version) {
this.version = version;
}
}(2)、持久化映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="learn.hibernate.bean">
<!--
optimistic-lock="version" 指定持久化类的乐观锁策略
-->
<class name="Person" table="t_person" optimistic-lock="version">
<id name="id" column="person_id">
<generator class="native"/>
</id>
<!-- 配置 锁字段和对应的属性关联,以及字段类型 -->
<version name="version" column="t_version" type="integer"/>
<property name="name" column="t_name"/>
<property name="age"/>
<property name="passwork"/>
<property name="birthday"/>
</class>
</hibernate-mapping>(3)、测试类
/**
* hibernate 在获取数据的时候返回一个锁状态
* 在提交数据的时候会自动的将锁状态进行改变
*/
@Test
public void testUpdate(){
Person p1 = (Person)s1.get(Person.class, 1);
Person p2 = (Person)s2.get(Person.class, 1); System.out.println("----------1---start-----------");
tx = s1.beginTransaction();
p1.setName("p1");
s1.update(p1);
tx.commit();
System.out.println("----------1---end-----------"); System.out.println("----------2---start-----------");
tx = s2.beginTransaction();
p2.setName("p2");
s2.update(p2);
tx.commit();
System.out.println("----------2---end-----------");
}
可以查看:http://blog.csdn.net/shen516/article/details/8599068
Hibernate学习---第十二节:Hibernate之锁机制&乐观锁实现的更多相关文章
- Mysql锁机制--乐观锁 & 悲观锁
Mysql 系列文章主页 =============== 从 这篇 文章中,我们知道 Mysql 并发事务会引起更新丢失问题,解决办法是锁.所以本文将对锁(乐观锁.悲观锁)进行分析. 第一部分 悲观锁 ...
- mysql行锁、表锁。乐观锁,悲观锁
锁定用于确保事务完整性和数据库一致性. 锁定可以防止用户读取其他用户正在更改的数据,并防止多个用户同时更改相同的数据. 如果不使用锁定,数据库中的数据可能在逻辑上变得不正确,而针对这些数据进行查询可能 ...
- Hibernate解决高并发问题之:悲观锁 VS 乐观锁
高并发问题是程序设计所必须要解决的问题,解决此类问题最主要的途径就是对对程序进行加锁控制.hibernate对加锁机制同样做出了实现,常用加锁方式为悲观锁和乐观锁.悲观锁指的是对数据被外界(包括本系统 ...
- 025 hibernate悲观锁、乐观锁
Hibernate谈到悲观锁.乐观锁,就要谈到数据库的并发问题,数据库的隔离级别越高它的并发性就越差 并发性:当前系统进行了序列化后,当前读取数据后,别人查询不了,看不了.称为并发性不好 数据库隔离级 ...
- Hibernate的悲观锁和乐观锁
前一篇博客我们从数据库角度分析,锁可以分为三种,分别为共享锁,独占锁和更新锁.我们从程序的角度来看锁可以分为两种类型,悲观锁和乐观锁,Hibernate提供对这两种锁 的支持,我们来了解一下Hiber ...
- Hibernate 再接触 悲观锁和乐观锁
为什么取1248 二进制 CRUD 移位效率高 在并发和效率选择一个平衡点 一般不会考虑幻读 因为我们不会再一个事务里查询两次,(只能设置为seralizable) 悲观锁和乐观锁的前提是read-u ...
- Hibernate学习一:Hibernate注解CascadeType
http://zy19982004.iteye.com/blog/1721846 ———————————————————————————————————————————————————————— Hi ...
- MySQL学习笔记(四)悲观锁与乐观锁
恼骚 最近在搞并发的问题,订单的异步通知和主动查询会存在并发的问题,用到了Mysql数据库的 for update 锁 在TP5直接通过lock(true),用于数据库的锁机制 Db::name('p ...
- mysql中的锁机制之悲观锁和乐观锁
1.悲观锁? 悲观锁顾名思义就是很悲观,悲观锁认为数据随时就有可能会被外界进行修改,所以悲观锁一上来就会把数据给加上锁.悲观锁一般都是依靠关系型数据库提供的锁机制,然而事实上关系型数据库中的行锁,表锁 ...
随机推荐
- ubuntu 16.04中卸载软件。
今天装了个QQ,结果不会用,折腾了半天终于卸载掉了. dpkg -l | grep qq(查出安装的软件) 使用 sudo dpkg --purge xxx(这里xxx写查出来的软件包名字)
- 2015年Android开发新技术盘点
又到年末. 利用中午的时间,汇总盘点一下今年Android开发方面的新技术.感觉如今Android开发没有曾经那么纯粹了,出现了非常多新的开发模式. 2015年影响比較普遍的新技术应该就是Materi ...
- jQuery Easy UI Draggable(拖动)组件
上文已经提到过了 jQuery EasyUI插件引用一般我们经常使用的有两种方式(排除easyload载入方式),所以本篇要总结的Draggable组件相同有两种方式载入: (1).使用class载入 ...
- 微信小程序 入门
目录结构: app.json .小程序的全局配置 pages: 当前小程序所有页面路径. window:小程序所有页面的顶部背景颜色,文字颜色定义在这里. tabBar: 设置底部 tab ne ...
- java.time.format.DateTimeFormatter
Java的日期与时间 DateTimeFormatter类是Java 8中日期时间功能里,用于解析和格式化日期时间的类,位于java.time.format包下. 1.预定义的DateTimeFo ...
- PAT 组合数的和(15)
给定N个非0的个位数字,用其中任意2个数字都可以组合成1个2位的数字.要求所有可能组合出来的2位数字的和.例如给定2.5.8,则可以组合出:25.28.52.58.82.85,它们的和为330. 输入 ...
- tfboys——tensorflow模块学习(一)
Tensorflow的基本使用 TensorFlow 的特点: 使用图 (graph) 来表示计算任务. 在被称之为 会话 (Session) 的上下文 (context) 中执行图. 使用 tens ...
- 常见数据挖掘算法的Map-Reduce策略(1)
大数据这个名词是被炒得越来越火了,各种大数据技术层出不穷,做数据挖掘的也跟着火了一把,呵呵,现今机器学习算法常见的并行实现方式:MPI,Map-Reduce计算框架,GPU方面,grap ...
- 初识机器学习之kNN算法
k近邻(k-Nearest Neighbor,简称kNN)学习是一种常用的监督学习方法,其工作机制非常简单:给定测试样本,基于某种距离度量找出训练集中与其最靠近的k个训练样本.然后基于这k个“邻居”的 ...
- C#泛型命名潜规则
public class List<T>{} public class LinkedList<T>{} public class SortedList<TKey,TVal ...