package org.zttc.itat.test;
import org.hibernate.LockOptions;
import org.hibernate.Session;
import org.junit.Test;
import org.zttc.itat.model2.Student;
import org.zttc.itat.util.HibernateUtil;
public class TestLock {
@Test<pre name="code" class="java"><?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.com.test.model">
<class name="Student" table="t_student">
<!-- <cache usage="read-only"/> -->
<id name="id">
<!-- <generator class="assigned"/> --><!-- 这个需要开发人员自己定义id -->
<generator class="native"/> <!-- 会自动生成一个字符串,此时主键必须为字符串 -->
</id>
<version name="version"/>
<property name="name"/>
<property name="sex"/>
<many-to-one name="classroom" column="c_id" fetch="select"/> <!-- fetch="join" -->
</class>
</hibernate-mapping>
package org.com.test.model;
//@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
public class Student {
private int id;
private String name;
private String sex;
private Classroom classroom;
private int version;
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public Student() {
}
public Student(String name, String sex, Classroom classroom) {
this.name = name;
this.sex = sex;
this.classroom = classroom;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Classroom getClassroom() {
return classroom;
}
public void setClassroom(Classroom classroom) {
this.classroom = classroom;
}
}
package org.com.test.test;
import org.com.test.model.Student;
import org.com.test.util.HibernateUtil;
import org.hibernate.Session;
import org.junit.Test;
public class TestLock {
@Test
public void testUpdate01() {
Session session = null;
try {
session = HibernateUtil.getSession();
session.beginTransaction();
//只要使用这种方式来load就会为其增加锁
// Student stu = (Student)session.load(Student.class,1,LockOptions.UPGRADE);
Student stu = (Student)session.load(Student.class, 1);
stu.setName("张三");
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
@Test
public void testUpdate02() {
Session session = null;
try {
session = HibernateUtil.getSession();
session.beginTransaction();
// Student stu = (Student)session.load(Student.class,1,LockOptions.UPGRADE);
Student stu = (Student)session.load(Student.class, 1);
stu.setSex("女");
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
}
一般并发会导致更新丢失,有两种解决方案可以解决并发的问题
1、悲观锁
悲观锁是Hibernate基于数据库的机制来实现的,hibernate是基于同步的机制实现的,当只要读取了这个对象,这个对象就会被加锁
只有在第一个对象读取完成之后第二个对象才能读取。这样将会大大的影响效率
2、乐观锁
乐观锁是在数据库中增加一个version的字段来实现的,每一次修改都会让这个字段的数字加1,在读取的时候根据version这个版本数据来读取
这样如果并发修改就会抛出异常