- 浏览: 448608 次
- 性别:
- 来自: 长沙
文章分类
- 全部博客 (168)
- Hibernate (17)
- MySQL (7)
- struts2 (14)
- Spring (12)
- Javascript (20)
- CSS (8)
- ajax/jquery (11)
- HttpClient (6)
- HTTP (1)
- java小知识 (23)
- Servlet/JSP (5)
- Oracle (0)
- Quartz (3)
- Lucene/Nutch (12)
- c# winform (2)
- J2ME (1)
- POI (5)
- php5 (2)
- DWR(Ajax) (1)
- log4j (1)
- dom4j (3)
- 獲取郵件聯系人 (2)
- 随意 (5)
- Heritrix (1)
- ireport+jasper (1)
- 算法 (2)
- java虚拟机 (1)
- maven (2)
最新评论
-
janrick:
太感谢了,我正需要加密的函数呢
java中DES加密解密例子 -
xuganggogo:
suyang119 写道请教一下,补充的三级的可以用吗?当然可 ...
关于条件查询detachedCriteria的注意的地方 -
suyang119:
请教一下,补充的三级的可以用吗?
关于条件查询detachedCriteria的注意的地方 -
xuganggogo:
大江帅 写道var name="attriName& ...
有关在JavaScript中使用EL表达式的问题 -
大江帅:
var name="attriName"; ...
有关在JavaScript中使用EL表达式的问题
乐观并发控制,可以有三种方式。
1,Version版本号
2,时间戳
3,自动版本控制。
这里不建议在新的应用程序中定义没有版本或者时间戳列的版本控制:它更慢,更复杂,如果你正在使用脱管对象,它则不会生效。
以下信息来自 : http://esffor.iteye.com/blog/168243
通过在表中及POJO中增加一个version字段来表示记录的版本,来达到多用户同时更改一条数据的冲突
数据库脚本:
POJO
public class Student ...{
private String id;
private String name;
private int version;
public String getId() ...{
return id;
}
public void setId(String id) ...{
this.id = id;
}
public String getName() ...{
return name;
}
public void setName(String name) ...{
this.name = name;
}
public int getVersion() ...{
return version;
}
public void setVersion(int version) ...{
this.version = version;
}
}
Student.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="Version.Student" table="studentVersion" >
<id name="id" unsaved-value="null">
<generator class="uuid.hex"></generator>
</id>
<!--version标签必须跟在id标签后面-->
<version name="version" column="ver" type="int"></version>
<property name="name" type="string" column="name"></property>
</class>
</hibernate-mapping>
Hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.username">root</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/schoolproject?characterEncoding=gb2312&useUnicode=true
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="myeclipse.connection.profile">mysql</property>
<property name="connection.password">1234</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.show_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="jdbc.batch_size">15</property>
<mapping resource="Version/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
测试代码:
import java.io.File;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Test ...{
public static void main(String[] args) ...{
String filePath=System.getProperty("user.dir")+File.separator+"src/Version"+File.separator+"hibernate.cfg.xml";
File file=new File(filePath);
System.out.println(filePath);
SessionFactory sessionFactory=new Configuration().configure(file).buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction t=session.beginTransaction();
Student stu=new Student();
stu.setName("tom11");
session.save(stu);
t.commit();
/**//*
* 模拟多个session操作student数据表
*/
Session session1=sessionFactory.openSession();
Session session2=sessionFactory.openSession();
Student stu1=(Student)session1.createQuery("from Student s where s.name='tom11'").uniqueResult();
Student stu2=(Student)session2.createQuery("from Student s where s.name='tom11'").uniqueResult();
//这时候,两个版本号是相同的
System.out.println("v1="+stu1.getVersion()+"--v2="+stu2.getVersion());
Transaction tx1=session1.beginTransaction();
stu1.setName("session1");
tx1.commit();
//这时候,两个版本号是不同的,其中一个的版本号递增了
System.out.println("v1="+stu1.getVersion()+"--v2="+stu2.getVersion());
Transaction tx2=session2.beginTransaction();
stu2.setName("session2");
tx2.commit();
}
}
运行结果:
Hibernate: insert into studentVersion (ver, name, id) values (?, ?, ?)
Hibernate: select student0_.id as id0_, student0_.ver as ver0_, student0_.name as name0_ from studentVersion student0_ where student0_.name='tom11'
Hibernate: select student0_.id as id0_, student0_.ver as ver0_, student0_.name as name0_ from studentVersion student0_ where student0_.name='tom11'
v1=0--v2=0
Hibernate: update studentVersion set ver=?, name=? where id=? and ver=?
v1=1--v2=0
Hibernate: update studentVersion set ver=?, name=? where id=? and ver=?
Exception in thread "main" org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Version.Student#4028818316cd6b460116cd6b50830001]
可以看到,第二个“用户”session2修改数据时候,记录的版本号已经被session1更新过了,所以抛出了红色的异常,我们可以在实际应用中处理这个异常,例如在处理中重新读取数据库中的数据,同时将目前的数据与数据库中的数据展示出来,让使用者有机会比较一下,或者设计程序自动读取新的数据
注意:
要注意的是,由于乐观锁定是使用系统中的程式来控制,而不是使用资料库中的锁定机制,因而如果有人特意自行更新版本讯息来越过检查,则锁定机制就会无效,例如在上例中自行更改stu的version属性,使之与资料库中的版本号相同的话就不会有错误,像这样版本号被更改,或是由于资料是由外部系统而来,因而版本资讯不受控制时,锁定机制将会有问题,设计时必须注意。
如果手工设置stu.setVersion()自行更新版本以跳过检查,则这种乐观锁就会失效,应对方法可以将Student.java的setVersion设置成private
发表评论
-
hibernate SQLQuery实践指南
2012-11-23 02:22 0http://fengqiaa.blog.163.com/bl ... -
Hibernate DTD <column>元素语法
2012-11-05 14:36 1084记录一下<column>元素的所有属性和用法 ... -
Hibernate DTD <column>元素语法
2012-11-05 14:36 0记录一下<column>元素的所有属性和用法 ... -
spring+hibernate,数据库插入图片
2010-05-10 16:26 1233主要就三個地方需要配置: <一>hbm中, & ... -
Hibernate3.2 核心包作用
2010-03-30 11:00 1115http://blog.csdn.net/liuwyong11 ... -
Sprint2.0 的findByCriteria() 会执行update
2010-02-08 18:31 619今天发现Hibernate的findByCriteria()方 ... -
hibernate疑惑
2009-11-03 11:53 1032hibernate学得不很深入,用hibernate用得越久疑 ... -
hibernate操作数据库 插入修改数据库默认值 dynamic-insert dynamic-update
2009-11-02 16:42 2068今天碰到类似的问题,文章转自http://hi.baidu.c ... -
hibernate datasource 配置详解
2009-08-05 10:50 14182对于某些数据库,例如Oracle来说,没有boolean数据类 ... -
hibernate Restrictions用法
2009-08-04 17:04 40123方法 说明 Restric ... -
hibernate的一对一(唯一外键关联)
2009-07-17 18:14 1926一:hibernate一对一唯一外键关联映射(单向关联Pe ... -
Hibernate 更灵活的用法 HibernateCallback
2009-06-16 12:54 2671在项目中用Hibernate的Deta ... -
DetachedCriteria查詢
2009-05-26 18:16 15591,最簡單簡單的查詢,分页: public List< ... -
关于条件查询detachedCriteria的注意的地方
2009-05-26 16:38 1596http://lingoosoft.blog.ccidnet. ... -
hibernate的各种保存方式的区别(saveOrUpdateCopy,merge和update…
2009-05-26 16:35 1746全文轉自:http://www.blogj ... -
one to many
2009-05-22 15:01 981one to many <!-- 類型包括的項目:類型 ... -
应用Hibernate3的DetachedCriteria实现分页查询
2009-05-04 11:33 1427http://www.iteye.com/topic/1465 ... -
hibernate分页
2009-05-04 10:33 1580Hibernate 可以实现分页查询,例如: 从第 ... -
Hibernate 支持三种继承映射策略
2009-02-01 16:12 17681,subclass 元素映射子类:用一张表存储整个继承树的 ...
相关推荐
下面我们将深入探讨Java中乐观锁的原理、实现方式以及其在实际开发中的应用。 乐观锁的核心思想是:在读取数据时不会加锁,而是在更新数据时才会检查在此期间是否有其他线程修改了该数据。如果在检查时发现有其他...
例如,Hibernate通过版本号机制实现乐观锁:在对象中添加一个版本号字段,并在映射文件中设置`optimistic-lock="version"`。当尝试更新数据时,如果版本号与数据库中的不匹配,更新将失败并抛出异常。这时,应用可以...
在Hibernate中,可以使用`@Version`注解轻松实现乐观锁。 ```java @Entity public class Account { @Id private int id; private String name; @Version private int version; // ...其他属性和方法 } `...
Hibernate支持乐观锁和悲观锁,通过@Version注解实现版本控制,防止并发更新时的数据冲突。 15. **JPA集成** Hibernate既是独立的ORM框架,也是Java Persistence API(JPA)的实现。开发者可以选择使用JPA规范,...
Hibernate的`@Version`注解实现了乐观锁,防止并发问题。 总结,Hibernate为Java开发人员提供了丰富的工具和策略,简化了数据库操作,提高了开发效率。理解和掌握这些操作,将有助于更好地利用Hibernate进行数据库...
7. **版本控制(Versioning)**:`hbnlab4_version`目录下的代码可能涉及到乐观锁的概念,这是Hibernate的一种版本控制机制,通过在实体中添加一个版本字段,防止并发更新时的数据冲突。 8. **继承策略...
这个注解用于指定乐观锁策略。例如: ```java @Entity public class Flight implements Serializable { @Version @Column(name = "OPTLOCK") private Integer version; // 其他属性和方法... } ``` `@...
同时,了解和熟悉JPA的缓存机制、乐观锁和悲观锁、级联操作等高级特性,能够帮助你写出更加优化的代码。 总的来说,JPA作为ORM的一种解决方案,极大地简化了Java应用与数据库之间的交互,提高了开发效率。在使用...
2. **<version>**:定义乐观锁版本字段,用于并发控制。 3. ****:映射类内的复杂类型或嵌入式对象。 4. **, , , **:这些集合类型的映射元素,用于处理一对多或多对多的关系。 在实际应用中,NHibernate通过读取...