文档章节

hibernate 版本(version)控制

Airship
 Airship
发布于 2017/01/23 14:31
字数 676
阅读 35
收藏 0

 Hibernate支持乐观锁。当多个事务同时对数据库表中的同一条数据操作时,如果没有加锁机制的话,就会产生脏数据(duty data)。Hibernate有2种机制可以解决这个问题:乐观锁和悲观锁。这里我们只讨论乐观锁。 
     Hibernate乐观锁,能自动检测多个事务对同一条数据进行的操作,并根据先胜原则,提交第一个事务,其他的事务提交时则抛出org.hibernate.StaleObjectStateException异常。 
    Hibernate乐观锁是怎么做到的呢? 
    我们先从Hibernate乐观锁的实现说起。要实现Hibenate乐观锁,我们首先要在数据库表里增加一个版本控制字段,字段名随意,比如就叫version,对应hibernate类型只能为 long,integer,short,timestamp,calendar,也就是只能为数字或timestamp类型。然后在hibernate mapping里作如下类似定义: 

    <version name="version" 
        column="VERSION" 
        type="integer"/> 

告诉Hibernate version作为版本控制用,交由它管理。 
当然在entity class里也需要给version加上定义,定义的方法跟其他字段完全一样。 
private Integer version; 
… 
// setVersion() && getVersion(Integer) 

Hibernate乐观锁的的使用: 
Session session1 = sessionFactory.openSession(); 
Session session2 = sessionFactory.openSession(); 
MyEntity et1 = session1.load(MyEntity.class, id); 
MyEntity et2 = session2.load(MyEntity.class, id); 
//这里 et1, et2为同一条数据 
Transaction tx1 = session1.beginTransaction(); 
//事务1开始 
et1.setName(“Entity1”); 
//事务1中对该数据修改 
tx1.commit(); 
session1.close(); 
//事务1提交 
Transaction tx2 = session2.beginTransaction(); 
//事务2开始 
et2.setName(“Entity2”); 
//事务2中对该数据修改 
tx2.commit(); 
session2.close(); 
//事务2提交 

在事务2提交时,因为它提交的数据比事务1提交后的数据旧,所以hibernate会抛出一个org.hibernate.StaleObjectStateException异常。 
回到前面的问题,Hibernate怎么知道事务2提交的数据比事务1提交后的数据旧呢? 
因为MyEntity有个version版本控制字段。 

回头看看上面的源代码中的: 
MyEntity et1 = session1.load(MyEntity.class, id); 
MyEntity et2 = session2.load(MyEntity.class, id); 
这里,et1.version==et2.version,比如此时version=1, 
当事务1提交后,该数据的版本控制字段version=version+1=2,而事务2提交时version=1<2所以Hibernate认为事务2提交的数据为过时数据,抛出异常。 
这就是Hibernate乐观锁的原理机制。 
我们已经知道了Hibernate乐观锁是根据version的值来判断数据是否过时,也就是说,在向数据库update某数据时,必须保证该entity 里的version字段被正确地设置为update之前的值,否则hibernate乐观锁机制将无法根据version作出正确的判断。 
在我们的WEB应用中,尤其应该注意这个问题。

本文转载自:http://blog.csdn.net/jston_learn/article/details/7539401

Airship
粉丝 45
博文 1009
码字总数 20464
作品 0
南京
高级程序员
私信 提问
Hibernate多事物并发访问控制

在并发环境,一个数据库系统会同时为各种各样的客户程序提供服务,也就是说,在同一时刻,会有多个客户程序同时访问数据库系统,这多个客户程序中的失误访问数据库中相同的数据时,如果没有采...

猴亮屏
2014/11/12
0
0
hibernate 锁机制

Hibernate 悲观锁,乐观锁1.悲观锁 它指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数据,为了保持数据被操作的一致性,于是对数据采取了数...

世界和平维护者
2016/07/21
11
0
Hibernate事务和并发控制

Hibernate事务和并发控制 ++YONG原创,转载请注明 1. 事务介绍: 1.1. 事务的定义: 事务就是指作为单个逻辑工作单元执行的一组数据操作,这些操作要么必须全部成功,要么必须全部失败,以保...

mrliuze
2015/06/03
0
0
hibernate 乐观锁与悲观锁使用

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

长平狐
2013/01/06
655
0
4.4 Hibernate高级功能

1.Hibernate批量处理 在Hibernate应用中,有两种批量处理方法:一种是通过Hibernate的缓存,另一种是绕过Hibernate,直接调用JDBC API来处理。 1)批量插入 (1)通过Hibernate的缓存进行批量...

JerryPan
2016/03/02
187
0

没有更多内容

加载失败,请刷新页面

加载更多

spring mvc主流程源码阅读(剖析)

第一步,通过web.xml的配置可以知道,用户访问url第一次先走到DispatchServlet,(默认你学过基本的java的Servlet开发) <servlet><servlet-name>springServlet</servlet-name><serv......

小海bug
21分钟前
2
0
vmstat命令详解

https://www.cnblogs.com/ggjucheng/archive/2012/01/05/2312625.html

流光韶逝
56分钟前
1
0
如何理解算法时间复杂度的表示

先从O(1) 来说,理论上哈希表就是O(1)。因为哈希表是通过哈希函数来映射的,所以拿到一个关键 字,用哈希函数转换一下,就可以直接从表中取出对应的值。和现存数据有多少毫无关系,故而每次执...

yky20190625
今天
6
0
分布式架构 实现分布式锁的常见方式

一、我们为什么需要分布式锁? 在单机时代,虽然不需要分布式锁,但也面临过类似的问题,只不过在单机的情况下,如果有多个线程要同时访问某个共享资源的时候,我们可以采用线程间加锁的机制...

太猪-YJ
今天
9
0
GitLab Docker 安装记录

安装环境 环境Centos7.4 64 1.拉取镜像文件 docker pull gitlab/gitlab-ce:latest 2.docker 安装 git.zddts.com 为访问域名或换成可以访问的IP docker run -d --hostname git.***.com -p ......

侠者圣
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部