Hibernate的悲观锁和乐观锁

原创 2012年03月21日 17:28:24
谈到悲观锁和乐观锁,就要谈到数据库的并发问题,数据库的隔离级别越高并发性就越差
并发性:
当前系统进行了序列化后,你读取数据库后,别人查询不了,称为并发性不好

1.悲观锁

具有排它性(我锁住当前数据后,比人看不到此数据),悲观锁一般是由数据库机制来做到的

悲观锁的实现:

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

悲观锁的适用场景:

悲观锁一般适合短事物比较多(如某一个数据取出后加1,立即释放)


实例:

用户1,用户2同时读取到数据,但是用户2先-200,这时数据库里的是800,现在用户1也开始-200,可以用户1刚才读取到的数据是1000,现在用户用刚一开始读取的数据1000-200,而用户1在更新时数据库里的数据是800,按理说用户1应该是800-200=600,这样就造成更新丢失。这种情况下可采用两种方式解决:悲观锁、乐观锁。
悲观锁:用户1读取数据后,用锁将其读取的数据锁上,这时用户2是读取不到数据的,只有用户1释放锁后用户2才可以读取,同样用户2读取数据的数据也锁上,这样就可以解决更新丢失了。

实体类:

public class Inventory {
	private int itemNo;	
	private String itemName;	
	private int quantity;
	public int getItemNo() {
		return itemNo;
	}
	public void setItemNo(int 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.cn.hibernate.Inventory" table="t_inventory">
		<id name="itemNo">
			<generator class="native"/>
		</id>
		<property name="itemName"/>
		<property name="quantity"/>
	</class>
</hibernate-mapping>

悲观锁的使用:

如果要使用悲观锁,肯定在加载数据时就要锁住,通常采用for update语句

Hibernate使用load进行悲观锁加载


Session.load(Class arg(),Serializable arg1,LockMode arg2)throws HibernateException

LockMode:悲观锁模式(一般使用LockMode.UPGRADE)

session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			Inventory inv = (Inventory)session.load(Inventory.class, 1, LockMode.UPGRADE);
			System.out.println(inv.getItemName());
			inv.setQuantity(inv.getQuantity()-200);
			
			session.update(inv);
			tx.commit();
如果使用悲观锁,那么lazy(懒加载)无效


2.乐观锁

乐观锁:不是锁,是一种冲突检测机制,乐观锁的并发性较好,因为我改的时候,别人可随便修改乐观锁的实现方式:常用的是版本的方式(每个数据表中有一个版本字段version,某一个用户更新数据库后,版本号+1,另一个用户修改后再+1,当用户更新发现数据库当前版本号与读取数据时版本号不一致,等于或小于数据库版本号则更新不了)

Hibernate使用乐观锁需要在映射文件中配置才可生效

实体类

public class Inventory {
	private int itemNo;	
	private String itemName;	
	private int quantity;	
	private int version;//Hibernate用户实现版本方式乐观锁,但需要在映射文件中配置
	public int getItemNo() {
		return itemNo;
	}
	public void setItemNo(int 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;
	}
	public int getVersion() {
		return version;
	}
	public void setVersion(int version) {
		this.version = version;
	}
}





                

java面试狂魔之hibernate悲观锁和乐观锁

HR:请谈谈Hibernate悲观锁和乐观锁的原理和应用场景? (ps:虽然现在很多企业都在用mybatis代替hibernate,但hibernate还是有一定地位的,此文仅供吐槽。吐吧。。。。) ...
  • FANTASY522272820
  • FANTASY522272820
  • 2016年03月29日 19:45
  • 1292

细谈Hibernate之悲观锁和乐观锁解决hibernate并发

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

Hibernate悲观锁/乐观锁

一,悲观锁 二,乐观锁
  • a19881029
  • a19881029
  • 2014年05月02日 11:36
  • 6529

hibernate 乐观锁与悲观锁使用

Hibernate支持两种锁机制:  即通常所说的“悲观锁(Pessimistic Locking)”和 “乐观锁(OptimisticLocking)”。  悲观锁的实现,往往依靠数据库提供...
  • u013614451
  • u013614451
  • 2014年11月06日 22:47
  • 1063

【hibernate框架】使用hibernate实现悲观锁和乐观锁

四种隔离机制不要忘记:(1,2,4,8) 1.read-uncommitted:能够去读那些没有提交的数据(允许脏读的存在) 2.read-committed:不会出现脏读,因为只有另一个事务提交才会...
  • u013517797
  • u013517797
  • 2015年03月10日 15:48
  • 2815

Hibernate的悲观锁和乐观锁

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

Hibernate的悲观锁并发控制机制及LockMode

1. 悲观锁的并发控制机制概述 默认事务之间会产生数据冲突,所以要求事务在读取数据的时候就对数据加锁; 该锁将一直被事务持有,直到事务结束才会释放锁。 2. Hibernate的悲观锁机制 Hibe...
  • taiyangdao
  • taiyangdao
  • 2016年07月22日 00:33
  • 2852

我们如何使用Hibernate的锁(悲观锁)

厚积薄发!!!
  • hushanfeng110
  • hushanfeng110
  • 2015年12月01日 19:30
  • 2421

Java程序员从笨鸟到菜鸟之(七十六)细谈Hibernate(十八)悲观锁和乐观锁解决hibernate并发

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

Hibernate乐观锁实现之Version

通过在表中及POJO中增加一个version字段来表示记录的版本,来达到多用户同时更改一条数据的冲突 数据库脚本:   create table studentVersion (id...
  • zmx729618
  • zmx729618
  • 2016年04月29日 17:05
  • 1025
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Hibernate的悲观锁和乐观锁
举报原因:
原因补充:

(最多只允许输入30个字)