apple0668
TDD,Agile,Scrum,Core Java,J2EE,Investment Blank
BlogJava
首页
新随笔
聚合
管理
随笔-61 评论-159 文章-0 trackbacks-0
系统学习hibernate之十二:hibernate中悲观锁和乐观锁
hibernate中经常用到当多个人对同一数据同时进行修改的时候,会发生脏数据,造成数据的不一致性,解决办法是可以通过悲观锁和乐观锁来实现。
悲观锁:在数据有加载的时候就给其进行加锁,直到该锁被释放掉,其他用户才可以进行修改,优点:数据的一致性保持得很好,缺点:不适合多个用户并发访问。当一个锁住的资源不被释放掉的时候,这个资源永远不会被其他用户进行修改,容易造成无限期的等待。
乐观锁:就是在对数据进行修改的时候,对数据才去版本或者时间戳等方式来比较,数据是否一致性来实现加锁。优点比较好。
1、在悲观锁中,只要在加载的时候,才去session中的load方法,进行枷锁,session.load(****.class,1,LockMode.UPDATE);
Hibernate将事务管理委托给底层的JDBC或者JTA,默认是基于JDBC Transaction的。
Hibernate支持“悲观锁(Pessimistic Locking)”和“乐观锁(Optimistic Locking)”。
悲观锁对数据被外界修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制。Hibernate通过使用数据库的for update子句实现了悲观锁机制。Hibernate的加锁模式有:
1. LockMode.NONE:无锁机制
2. LockMode.WRITE:Hibernate在Insert和Update记录的时候会自动获取
3. LockMode.READ:Hibernate在读取记录的时候会自动获取
4. LockMode.UPGRADE:利用数据库的for update子句加锁
5. LockMode.UPGRADE_NOWAIT:Oracle的特定实现,利用Oracle的for update nowait子句实现加锁
2、
乐观锁大多是基于数据版本(Version)记录机制实现。Hibernate在其数据访问引擎中内置了乐观锁实现,可以通过class描述符的optimistic-lock属性结合version描述符指定。optimistic-lock属性有如下可选取值:
1. none:无乐观锁
2. version:通过版本机制实现乐观锁
3. dirty:通过检查发生变动过的属性实现乐观锁
4. all:通过检查所有属性实现乐观锁
例子:
1、悲观锁:
1>POJO类
public class PersimisticLocking {
private int id;
private String Item;
private int price;
//省略setter、getter方法
}
2>、POJO类的映射文件
1
<?
xml version="1.0"
?>
2
<!
DOCTYPE hibernate-mapping PUBLIC
3
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
5
<
hibernate-mapping
package
="org.apple.hibernate"
>
6
<
class
name
="PersimisticLocking"
table
="t_persimisticLocking"
>
7
<
id
name
="id"
>
8
<
generator
class
="native"
/>
9
</
id
>
10
<
property
name
="item"
/>
11
<
property
name
="price"
/>
12
</
class
>
13
</
hibernate-mapping
>
3>、加载测试方法
1
public
void
testLoad1()
2
{
3
Session session
=
null
;
4
try
{
5
session
=
HibernateUtil.getSession();
6
session.beginTransaction();
7
OptimisticLocking o
=
(OptimisticLocking)session.load(OptimisticLocking.
class
,
1
);
8
System.out.println(
"
o.item=
"
+
o.getItem());
9
System.out.println(
"
o.price=
"
+
o.getPrice());
10
System.out.println(
"
o.version=
"
+
o.getVersion());
11
o.setPrice(o.getPrice()
-
10
);
12
session.update(o);
13
session.beginTransaction().commit();
14
}
catch
(Exception e)
{
15
//
TODO: handle exception
16
e.printStackTrace();
17
session.beginTransaction().rollback();
18
}
finally
{
19
HibernateUtil.closeSession(session);
20
}
21
22
}
PS:可以设置另外类似的方法,不枷锁,先对上面的测试代码设置断点,点debug一部分,再运行不枷锁的,可以看到,如果上面方法不释放锁的话,下面的数据就会造成无限期的等待。
2、乐观锁:
1>在悲观锁的基础上加入private int version;和相关的setter、getter方法。
2>映射文件配置在class标签里面加入
optimistic-lock="version"
,然后在的id标签后面加入<version name=
"version"/>
3>测试方法:
1
public
void
testLoad1()
2
{
3
Session session
=
null
;
4
try
{
5
session
=
HibernateUtil.getSession();
6
session.beginTransaction();
7
OptimisticLocking o
=
(OptimisticLocking)session.load(OptimisticLocking.
class
,
1
);
8
System.out.println(
"
o.item=
"
+
o.getItem());
9
System.out.println(
"
o.price=
"
+
o.getPrice());
10
System.out.println(
"
o.version=
"
+
o.getVersion());
11
o.setPrice(o.getPrice()
-
10
);
12
session.update(o);
13
session.beginTransaction().commit();
14
}
catch
(Exception e)
{
15
//
TODO: handle exception
16
e.printStackTrace();
17
session.beginTransaction().rollback();
18
}
finally
{
19
HibernateUtil.closeSession(session);
20
}
21
22
}
PS:在初始数据的时候,version为0,在没更新一次version都会在原来的基础上加1,通过version的版本来实现乐观锁。
在上面的测试方法里面复制成另外一个方法,对上面的方法进行设置断点,然后单步调试几部,到NO.11行的时候暂停,此时对复制的另外方法运行,然后再运行完上面的方法,就会抛出异常,所以,在实际的项目开发中,可以通过对异常进行出来,这样就会实现并发访问。
-------------------------------------------------------------------------------------------------
PS:本博客文章,如果没有注明是有“转”字样,属于本人原创。如果需要转载,务必
注明作者
和
文章的详细出处地址
,否则不允许转载,多谢合作!
posted on 2008-10-27 23:48
apple0668
阅读(1440)
评论(0)
编辑
收藏
所属分类:
hibernate
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
管理
相关文章:
系统学习hibernate之十五:hibernate一级缓存
系统学习hibernate之十四:hibernate中HQL查询语言(二)
系统学习hibernate之十三:hibernate中HQL查询语言(一)
系统学习hibernate之十二:hibernate中悲观锁和乐观锁
系统学习hibernate之十一:set、list、map、array集合
系统学习hibernate之十:Component映射
系统学习hibernate之九:多对多关联映射(双向)
系统学习hibernate之八:多对多关联映射(单向)
系统学习hibernate之七:一对多单向关联
系统学习hibernate之六:一对一外键关联映射双向关联
Email:
chensp1230@163.com
欢迎交流
框架是告诉人们不该去做什么,而不是告诉人们该去做什么;容器是告诉人们该去做什么,而不是告诉人们不该去做什么!
<
2008年10月
>
日
一
二
三
四
五
六
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
留言簿
(10)
给我留言
查看公开留言
查看私人留言
我参与的团队
深圳Java俱乐部(0/0)
Netbeans 爱好者(0/0)
随笔分类
(63)
Aglets(1)
drools(2)
eclipse(6)
groovy
hibernate(17)
java(7)
jboss
junit(3)
Log4(2)
MongoDB(1)
oracle(1)
spring(4)
struts2(8)
svn(1)
tomcat(4)
webwork(4)
web报表(1)
xml
心情港湾
集群(1)
随笔档案
(61)
2015年3月 (1)
2012年7月 (1)
2012年4月 (1)
2011年5月 (3)
2010年1月 (2)
2009年3月 (1)
2008年12月 (2)
2008年11月 (5)
2008年10月 (16)
2008年9月 (1)
2008年4月 (1)
2008年1月 (2)
2007年11月 (2)
2007年10月 (15)
2007年9月 (8)
友情链接
开源在线手册
最新随笔
1. Ehcache集群方案
2. MongoDB安装手记
3. 任何人都可以重构<转载>
4. JDK6中JWS自带webservice应用
5. 解决:Eclipse启动tomcat 访问不了 手动启动可以访问
6. IntelliJ Idea10 常用快捷键
7. Drools语法详解<转>
8. eclipse3.4安装drools插件手记
9. Java日期时间运算
10. java中使用功能强悍的正则表达式
搜索
最新评论
1. re: Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记
非常感谢楼主分享,解决问题, Tomcat 7.0.59
--Gozs
2. re: Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记[未登录]
正解
--gao
3. re: Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记
@123
已解决,谢谢提示myeclipse相关的有用信息~~
--sequoah
4. re: Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记
赞 清空work文件夹就可以了
--维尼
5. re: Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记
很好 问题解决了!
--兔兔
阅读排行榜
1. Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记(85498)
2. 系统学习hibernate之一:利用hibernate中的SchemaExport生成数据表(18630)
3. eclipse的第一个struts2插件:Alveole Studio MVC Web Project An eclipse plugin for Struts 2(15667)
4. Subversion之路---实现精细的目录访问权限控制<转>(11261)
5. IntelliJ Idea10 常用快捷键(9302)
评论排行榜
1. Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记(62)
2. eclipse的第一个struts2插件:Alveole Studio MVC Web Project An eclipse plugin for Struts 2(32)
3. Tomcat启动端口被占用异常处理(9)
4. 升级瑞星防火墙2008后,在myeclipse6.0中启动tomcat遇到怪问题!(7)
5. JDK6中JWS自带webservice应用(6)