文档章节

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

小强斋太
 小强斋太
发布于 2016/11/09 20:07
字数 676
阅读 3
收藏 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) 


 

 

小强斋太
粉丝 0
博文 181
码字总数 0
作品 0
广州
私信 提问
加载中
请先登录后再评论。
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
4.1K
3
高效 Java Web 开发框架--JessMA

JessMA 是功能完备的高性能 Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 DAO 数据库访问组件(内部已提供了 Hibernate、MyBatis 与 JDBC DAO 组件),集成了 Action 拦截...

伤神小怪兽
2012/11/13
9.2K
3
高效率的nio框架--nio java raptor

设计初衷是提供方便易用,且高效率的nio框架,一部分实现上参考了mina。还包括线程池,编解码,内存池等机制,以便于开发高性能tcp程序。 文档后续会慢慢的补上。 整体实现上尽量少的使用锁,...

齐楠
2012/12/12
3.3K
0
C多线程网络库--xs

基于C多线程网络库,欢迎大家使用,例子在代码example目录下,以后我会再增加一些例子。 文档暂时没有,有问题请邮件我:-) 获取代码:https://github.com/xueguoliang/xs xs致力于1)多线程网...

薛国良
2013/05/01
4.4K
0
Lisp的STM库--STMX

STMX 是一个高性能的 Common Lisp 库,用于实现可组合的软件事务内存机制。 事务内存是一种并行程序设计的方式,其来自于数据库管理系统(DBMS)中的事务(Transaction)概念。事务内存目前有...

匿名
2013/05/09
814
0

没有更多内容

加载失败,请刷新页面

加载更多

Azure Application Gateway(一)对后端 Web App 进行负载均衡

一,引言   今天,我们学习一个新的知识点-----Azure Application Gateway,通过Azure 应用程序网关为我么后端的服务提供负载均衡的功能。我们再文章头中大概先了解一下什么是应用程序网关...

osc_lc4icfkt
32分钟前
4
0
WoLai(我来) 注册码 ——国内版 notion 【笔记】

注册码: SQGYG23 ❤ W4T9PKP JLTHNJP KMTXK7P JDHKJEM KRJXX5P 6M7PPAP DEGLMG3 N3BZMRI 87BR22I GSIWGWP GNGBNTI QA8URIM UDUV9VM IHKJA7P MD9ZA3M 3XR67ZI TBUP9JX TI4TYMM 注册完了可以把......

osc_c05lkk3u
33分钟前
15
0
2020hdu多校第二场比赛及补题

这一场我们队只A了一题 1010 Lead of Wisdom 直接爆搜,但是T了好几发,剪了下枝 如果一个物品的a,b,c,d都比不上另外一个同种物品的a,b,c,d,那这个物品就可以直接淘汰掉了 #include<iostrea...

osc_usgpahnw
34分钟前
21
0
为什么Java有瞬态字段? - Why does Java have transient fields?

问题: 为什么Java有瞬态字段? 解决方案: 参考一: https://stackoom.com/question/3opS/为什么Java有瞬态字段 参考二: https://oldbug.net/q/3opS/Why-does-Java-have-transient-fields...

富含淀粉
34分钟前
16
0
轻松搭建CAS 5.x系列(6)-在CAS Server上增加OAuth2.0协议

概述说明 CAS Server默认搭建出来,客户端程序只能按照CAS自身的协议接入。CAS的强大在于,有官方的插件,可以支持其他的协议。本章节就让CAS Server怎么增加OAuth2.0的登录协议。 安装步骤 ...

osc_inj0cicw
36分钟前
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部