Hibernate:并发控制
Hibernate:并发控制
.实体类:Student.java
public class Student {
private Integer sid;
private String sname;
private Integer version;
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
}
2.hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 1. 数据库相关 -->
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 连接MySQL数据库 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 2.配置本地事务(No CurrentSessionContext configured!) -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 3. 调试相关 -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- 4.hibernate需要管理的数据库表对应的实体类映射文件 -->
<mapping resource="com/zking/two/entity/student.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
3.student.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="t_hibernate_student" name="com.zking.two.entity.Student">
<id name="sid" type="java.lang.Integer" column="sid">
<generator class="increment"></generator>
</id>
<!-- version需写在property前面,否则会报错 -->
<version name="version" type="java.lang.Integer" column="versionqq"></version>
<property name="sname" type="java.lang.String" column="sname"></property>
</class>
</hibernate-mapping>
4.测试代码:
dao方法:
public class StudentDao {
//修改方法
public void updateStudent(Student student) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
session.update(student);
transaction.commit();
session.close();
}
}
测试类:Junit 测试
public class StudentDaoTest {
@Test
public void testUpdateStudent() {
Student stu=new Student();
stu.setSid(7);
stu.setSname("哈哈哈");
/*stu.setVersion(1);*/ //第一次修改
stu.setVersion(2); //第二次修改
this.userDao.updateStudent(stu);
}
}
第一次修改时可以修改,第二次已不能修改,
因为versionqq已改变,为2,hibernate自动给versionqq加1
如若要再次进行修改,把最新信息传过来即可,即stu.setVersion(2);
第一个修改方法执行之后,再次执行的话,会报错:
(Exception in thread “main” org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):
可以看到,如果第二次执行修改数据时,记录的版本号已经被更新过了,所以抛出了红色的异常,我们可以在实际应用 中处理这个异常,例如在处理中重新读取数据库中的数据,同时将目前的数据与数据库中的数据展示出来,让使用者有机会比较一下,或者设计程序自动读取新的数 据