文档章节

hibernate---->悲观锁和乐观锁

小强斋太
 小强斋太
发布于 2016/11/09 20:07
字数 676
阅读 0
收藏 0
点赞 0
评论 0

一、悲观锁

悲观锁的实现,通常依赖于数据库机制,在整个过程中将数据锁定,其它任何用户都不能读取或修改

悲观锁的实现:

显式的用户指定"可以通过以下几种方式之一来表示:

  • 调用 Session.load()的时候指定锁定模式(LockMode)。

  • 调用Session.lock()。

  • 调用Query.setLockMode()。

package com.wsz.test;

import junit.framework.TestCase;

import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.wsz.entity.HibernateUtils;
import com.wsz.entity.Products;

public class Test extends TestCase {

	public void testSave() {
		Session session = null;
		Transaction tx = null;
		Products products = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
            products=new Products();
            products.setName("脑白金");
            products.setTotalnumber(1000);
            session.save(products);
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}

	}

	public void test1() {

		Products products = new Products();
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		//悲观锁的实现
		products = (Products) session.load(products.getClass(), 1,LockMode.UPGRADE);
		System.out.print(products.getName());
		System.out.println(products.getTotalnumber());
		products.setTotalnumber(products.getTotalnumber()-200);
		session.getTransaction().commit();

	}
	
	
	public void test2() {

		Products products = new Products();
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		products = (Products) session.load(products.getClass(), 1,LockMode.UPGRADE);
		System.out.print(products.getName());
		System.out.println(products.getTotalnumber());
		products.setTotalnumber(products.getTotalnumber()-200);
		session.getTransaction().commit();

	}

}

使用悲观锁,lazy属性失效,立即发出sql。

二、乐观锁

大多数基于数据版本记录机制(version)实现,一般是在数据库表中加入一个version字段,读取数据时将版本号一同读出,之后更新数据时版本号加一,如果提交数据时版本号小于或等于数据表中的版本号,则认为数据是过期的,否则给予更新。

Products.hbm.xml

<hibernate-mapping>
	<class name="com.wsz.entity.Products" table="t_products" optimistic-lock="version">
		<id name="id">
			<generator class="native" />
		</id>
		<version name="version"/>
		<property name="name" />
		<property name="totalnumber" />
	</class>
</hibernate-mapping>

数据库表多了一个version字段

开始version=0

如果更新后 version=1,由数据库自动更新。

Products.java

package com.wsz.entity;


public class Products {
	private int id;
	private String name;
	private int  totalnumber;
	private int version;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getTotalnumber() {
		return totalnumber;
	}
	public void setTotalnumber(int totalnumber) {
		this.totalnumber = totalnumber;
	}
	public int getVersion() {
		return version;
	}
	public void setVersion(int version) {
		this.version = version;
	}
	



}

Test.java

package com.wsz.test;

import junit.framework.TestCase;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.wsz.entity.HibernateUtils;
import com.wsz.entity.Products;

public class Test extends TestCase {

	public void testSave() {
		Session session = null;
		Transaction tx = null;
		Products products = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
            products=new Products();
            products.setName("naobaijin");
            products.setTotalnumber(1000);
            session.save(products);
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}

	}

	public void test1() {

		Products products = new Products();
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		//悲观锁的实现
		products = (Products) session.load(products.getClass(), 1);
		System.out.print(products.getName());
		System.out.println(products.getTotalnumber());
		products.setTotalnumber(products.getTotalnumber()-200);
		session.getTransaction().commit();

	}
	
	
	public void test2() {

		Products products = new Products();
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		products = (Products) session.load(products.getClass(), 1);
		System.out.print(products.getName());
		System.out.println(products.getTotalnumber());
		products.setTotalnumber(products.getTotalnumber()-200);
		session.getTransaction().commit();

	}

}

使用悲观锁,lazy不会失效,不会立即发出sql

更新时发出的sql语句Hibernate: update t_products set version=?, name=?, totalnumber=? where id=? and version=?,

如果test1更新了,在commit设置断点,没有提交,test2更新了。此时test1往下运行,当前的version 小于数据库的version ,会生成如下的异常。

10:48:59,260 ERROR AbstractFlushingEventListener:301 - Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.wsz.entity.Products#1]
 at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1699) 


 

 

本文转载自:http://www.cnblogs.com/xqzt/archive/2012/09/06/5637187.html

共有 人打赏支持
小强斋太
粉丝 0
博文 181
码字总数 0
作品 0
广州
Java程序员从笨鸟到菜鸟之(七十六)细谈Hibernate(十八)悲观锁和乐观锁解决hibernate并发

锁( locking ),这个概念在我们学习多线程的时候曾经接触过,其实这里的锁和多线程里面处理并发的锁是一个道理,都是暴力的把资源归为自己所有。这里我们用到锁的目的就是通过一些机制来保...

长平狐 ⋅ 2012/11/12 ⋅ 0

悲观锁和乐观锁

下面先就乐观锁与悲观锁的概念及基本用法做下介绍,因为网上的已经比较详细,就直接摘抄了 锁( locking ) 业务逻辑的实现过程中,往往需要保证数据访问的排他性。如在金融系统的日终结算 ...

胡阳 ⋅ 2014/03/24 ⋅ 0

Hibernate数据库的并发

7、数据库的并发:当多个用户同时修改数据库时的处理。这一部分只是在一些特殊情况才考虑。 7.1、并发修改可能出现的问题 当两个线程同时修改一个对象时,后操作的对象会将前一个操作对象所更...

pmos ⋅ 2016/10/25 ⋅ 0

hibernate 乐观锁与悲观锁使用

总结一句话概述 当多个事务同时使用相同数据时会导致并发问题,此时只能用锁来限制。 悲观锁:直接锁住数据库,一个用完,下个才能用,开销大。 乐观锁:数据库中增大version字段,每次提交时...

长平狐 ⋅ 2013/01/06 ⋅ 0

Hibernate的乐观锁与悲观锁

转帖:谢谢分享 锁( locking ) 业务逻辑的实现过程中,往往需要保证数据访问的排他性。如在金融系统的日终结算处理中,我们希望针对某个 cut-off 时间点的数据进行处理,而不希望在结算进行...

four ⋅ 2011/03/24 ⋅ 0

乐观锁悲观锁

锁( locking ) 业务逻辑的实现过程中,往往需要保证数据访问的排他性。如在金融系统的日终结算 处理中,我们希望针对某个 cut-off 时间点的数据进行处理,而不希望在结算进行过程中 (可能...

pczhangtl ⋅ 2013/11/18 ⋅ 0

Hibernate(五)——面向对象查询语言和锁

Hibernate做了数据库中表和我们实体类的映射,使我们不必再编写sql语言了。但是有时候查询的特殊性,还是需要我们手动来写查询语句呢,Hibernate框架为了解决这个问题给我们提供了HQL(Hiber...

凡尘里的一根葱 ⋅ 2015/11/11 ⋅ 0

Hibernate事务与并发问题处理(乐观锁与悲观锁) [转]

Hibernate事务与并发问题处理(乐观锁与悲观锁) 一、数据库事务的定义   数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作。事务处理可以确保除非事务性单元...

祥子哥哥 ⋅ 2014/06/10 ⋅ 0

MySQL数据库的锁机制

在并发访问情况下,很有可能出现不可重复读等等读现象。为了更好的应对高并发,封锁、时间戳、乐观并发控制(乐观锁)、悲观并发控制(悲观锁)都是并发控制采用的主要技术方式。 锁分类 ①、按操...

Javahih ⋅ 01/02 ⋅ 0

大数据下高并发的处理详解

对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了。而并发问题是绝大部分的程序员头疼的问题,但话又说回来了,既然逃避不掉,那我们就要想想应对措...

商者 ⋅ 2016/07/18 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

关于线程的创建

转自自己的笔记: http://note.youdao.com/noteshare?id=87584d4874acdeaf4aa027bdc9cb7324&sub=B49E8956E145476191C3FD1E4AB40DFA 1.创建线程的方法 Java使用Thread类代表线程,所有的线程对......

MarinJ_Shao ⋅ 28分钟前 ⋅ 0

工厂模式学习

1. 参考资料 工厂模式-伯乐在线 三种工厂-思否 深入理解工厂模式 2. 知识点理解 2.1 java三种工厂 简单工厂 工厂模式 抽象工厂 2.2 异同点 逐级复杂 简单工厂通过构造时传入的标识来生产产品...

liuyan_lc ⋅ 40分钟前 ⋅ 0

Java NIO

1.目录 Java IO的历史 Java NIO之Channel Java NIO之Buffer Java NIO之Selector Java NIO之文件处理 Java NIO之Charset Java 可扩展IO 2.简介 “IO的历史”讲述了Java IO API从开始到现在的发...

士别三日 ⋅ 44分钟前 ⋅ 0

[Err] ORA-24344: success with compilation error

从txt文本复制出创建function的脚本,直接执行,然后报错:[Err] ORA-24344: success with compilation error。 突然发现脚本的关键字,居然不是高亮显示。 然后我把脚本前面的空格去掉,执行...

wenzhizhon ⋅ 53分钟前 ⋅ 0

Spring Security授权过程

前言 本文是接上一章Spring Security认证过程进一步分析Spring Security用户名密码登录授权是如何实现得; 类图 调试过程 使用debug方式启动https://github.com/longfeizheng/logback该项目,...

hutaishi ⋅ 今天 ⋅ 0

HAProxy基于KeepAlived实现Web高可用及动静分离

前言 软件负载均衡一般通过两种方式来实现: 基于操作系统的软负载实现 基于第三方应用的软负载实现 LVS是基于Linux操作系统实现的一种软负载,而HAProxy则是基于第三方应用实现的软负载。 ...

寰宇01 ⋅ 今天 ⋅ 0

微软自研处理器的小动作:已经开始移植其他平台的工具链

微软将 Windows 10 、Linux 以及工具链如 C/C++ 和 .NET Core 运行时库、Visual C++ 2017 命令行工具、RyuJIT 编辑器等移植到其自主研发的处理器架构 E2。微软还移植了广泛使用的 LLVM C/C++...

linux-tao ⋅ 今天 ⋅ 0

JS常见this指代总结

1. dom0级事件处理程序的回调函数内 2. dom2级事件处理程序的回调函数内 3. setTimeout 4. setInterval var test = { testfn: function () { console.log(this); }};...

静默行 ⋅ 今天 ⋅ 0

泛型的基本原理

泛型是 JDK1.5 的一个新特性,其实就是一个『语法糖』,本质上就是编译器为了提供更好的可读性而提供的一种小「手段」,虚拟机层面是不存在所谓『泛型』的概念的。 在我看来,『泛型』的存在...

沧海一刀 ⋅ 今天 ⋅ 0

学好Java只需要做到这8点,年薪30W很简单!文末福利赠送!

前言: 大道至简,所以扎实有用的方法,其实都是很简单的,难在踏踏实实的执行过程。今天为大家介绍的就是Java学习的8个看起来非常简单的方法,快学起来吧。 为什么要学习Java? Java是目前最...

java高级架构牛人 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部