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之锁机制&乐观锁实现的更多相关文章

  1. Mysql锁机制--乐观锁 & 悲观锁

    Mysql 系列文章主页 =============== 从 这篇 文章中,我们知道 Mysql 并发事务会引起更新丢失问题,解决办法是锁.所以本文将对锁(乐观锁.悲观锁)进行分析. 第一部分 悲观锁 ...

  2. mysql行锁、表锁。乐观锁,悲观锁

    锁定用于确保事务完整性和数据库一致性. 锁定可以防止用户读取其他用户正在更改的数据,并防止多个用户同时更改相同的数据. 如果不使用锁定,数据库中的数据可能在逻辑上变得不正确,而针对这些数据进行查询可能 ...

  3. Hibernate解决高并发问题之:悲观锁 VS 乐观锁

    高并发问题是程序设计所必须要解决的问题,解决此类问题最主要的途径就是对对程序进行加锁控制.hibernate对加锁机制同样做出了实现,常用加锁方式为悲观锁和乐观锁.悲观锁指的是对数据被外界(包括本系统 ...

  4. 025 hibernate悲观锁、乐观锁

    Hibernate谈到悲观锁.乐观锁,就要谈到数据库的并发问题,数据库的隔离级别越高它的并发性就越差 并发性:当前系统进行了序列化后,当前读取数据后,别人查询不了,看不了.称为并发性不好 数据库隔离级 ...

  5. Hibernate的悲观锁和乐观锁

    前一篇博客我们从数据库角度分析,锁可以分为三种,分别为共享锁,独占锁和更新锁.我们从程序的角度来看锁可以分为两种类型,悲观锁和乐观锁,Hibernate提供对这两种锁 的支持,我们来了解一下Hiber ...

  6. Hibernate 再接触 悲观锁和乐观锁

    为什么取1248 二进制 CRUD 移位效率高 在并发和效率选择一个平衡点 一般不会考虑幻读 因为我们不会再一个事务里查询两次,(只能设置为seralizable) 悲观锁和乐观锁的前提是read-u ...

  7. Hibernate学习一:Hibernate注解CascadeType

    http://zy19982004.iteye.com/blog/1721846 ———————————————————————————————————————————————————————— Hi ...

  8. MySQL学习笔记(四)悲观锁与乐观锁

    恼骚 最近在搞并发的问题,订单的异步通知和主动查询会存在并发的问题,用到了Mysql数据库的 for update 锁 在TP5直接通过lock(true),用于数据库的锁机制 Db::name('p ...

  9. mysql中的锁机制之悲观锁和乐观锁

    1.悲观锁? 悲观锁顾名思义就是很悲观,悲观锁认为数据随时就有可能会被外界进行修改,所以悲观锁一上来就会把数据给加上锁.悲观锁一般都是依靠关系型数据库提供的锁机制,然而事实上关系型数据库中的行锁,表锁 ...

随机推荐

  1. Wormholes - poj 3259 (Bellman-Ford算法)

      Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 34934   Accepted: 12752 Description W ...

  2. 第三篇:Logstash 安装配置

    Logstash 简介: Logstash 是一个实时数据收集引擎,可收集各类型数据并对其进行分析,过滤和归纳.按照自己条件分析过滤出符合数据导入到可视化界面.Logstash 建议使用java1.8 ...

  3. 苹果mac shell 终端 命令行快捷键——行首行尾

    ctrl+a //移到行首 ctrl+e //移到行尾 http://blog.csdn.net/hherima/article/details/47083739

  4. 转载 【iOS开发】网页JS与OC交互(JavaScriptCore) OC ----->JS

      目标 本文介绍利用苹果在iOS7时发布的JavaScriptCore.framework框架进行js与OC的交互.我们想要达到的目标是: OC调用网页上的js方法 网页js调用APP中的OC方法 ...

  5. [Sdoi2013]随机数生成器(BSGS)

    #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #inclu ...

  6. Bootstrap 第一天

    Bootstrap第一天 1.什么是Bootstrap?     Bootstrap是由两位设计开发的.     Bootstrap主要是前端的框架(HTML.CSS.JS). 2.为什么使用Boot ...

  7. Linux内核设计基础(九)之进程管理和调度

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/BlueCloudMatrix/article/details/30799225 在Linux中进程用 ...

  8. LDA中的先验知识

    LDA涉及到的先验知识有:二项分布.Gamma函数.Beta分布.多项分布.Dirichlet分布.马尔科夫链.MCMC.Gibbs Sampling.EM算法等. 二项分布 二项分布是N重伯努利分布 ...

  9. 读paper:image caption with global-local attention…

    最近的图片caption真的越来越火了,CVPR ICCV ECCV AAAI很多顶级会议都有此类的文章,今天我来讲一篇发表在AAAI的文章,因为我看了大量的论文,最近感觉AAAI越来越水了.所以这篇 ...

  10. Android app与PC端交互

    app提交信息到PC端mysql数据库 新建名为SignActivity package com.example.administrator.success; import android.app.A ...