首先, 介绍下hibernate 提供的乐观锁:
在多线程的情况下, 不同线程中的事务想要拿同一个对象, 如果这个对象加了乐观锁, 那么所有的事务都能拿到这个对象( 即select 语句有值返回 ), 无论你拿这个对象是不是为了修改它. 不同的事务就可以对这个对象做各自的操作. 在提交事务的时候, 如果大家都修改了这个对象的属性, 那么先提交的事务正常提交, 后面提交的事务, 由于它对该对象的操作是基于错误的数据, 所以会进行事务回滚.
下面是示例代码:
public void testLock2(){
Session session1 = HibernateUtil.getInstance().getSession();
Session session2 = HibernateUtil.getInstance().getSession();
session1.beginTransaction();
session2.beginTransaction();
Employee e1 = session1.get(Employee.class,1L);
Employee e2 = session2.get(Employee.class, 1L);
e1.setName("update1");
e2.setName("update2");
session2.getTransaction().commit();
try {
session1.getTransaction().commit();
} catch (javax.persistence.OptimisticLockException e) {
System.out.println("系统正忙,请稍后.");
}
session2.close();
session1.close();
}
其中, Employee 需要提供一个Integer 类型的version, 交由hibernate 进行管理:
<hibernate-mapping package="cd.itcast.day5.cache">
<class name="Employee" table="employee">
<!-- 放入二级缓存 -->
<!-- <cache usage="read-only"/> -->
<id name="id" column="id">
<generator class="org.hibernate.id.enhanced.TableGenerator">
<param name="segment_value">IdDomain</param>
<param name="initial_value">1</param>
<param name="increment_size">1</param>
</generator>
</id>
<version name="version"/>
<property name="name" column="name"/>
</class>
</hibernate-mapping>