业务逻辑的实现过程中,往往需要保证数据访问的排他性。因此,我们就需要通过一些机制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,也就是所谓的“锁”,即给我们选定的目标数据上锁,使其无法被其它程序修改。
Hibernate 支持两种锁机制:
1. 悲观锁(Pessimistic Locking)从加载对象就开始锁定。修改过程中一直是锁。直到事务commit()提交后再解锁。
session.load(Info.class,"p003",LockOptions.UPGRADE);
public class TestPessimisticLock extends TestCase { @Test public void testLock1(){ Session session = null; try { session = HibernateUtil.getSession();//开始锁定,下面的testLock2不能执行 session.beginTransaction(); Info data = session.load(Info.class, "p003", LockOptions.UPGRADE); data.setName("1111111"); session.getTransaction().commit();//执行以后才解锁,这时testLock2才可以执行 } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally{ HibernateUtil.closeSession(); } } @Test public void testLock2(){ Session session = null; try { session = HibernateUtil.getSession(); session.beginTransaction(); Info data = session.load(Info.class, "p003", LockOptions.UPGRADE); data.setName("2222222"); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally{ HibernateUtil.closeSession(); } } }
2. 乐观锁(Optimistic Locking)并不是真的锁,是在提交时间进行冲突检测。把里面的内容与刚开始读取的内容对照一下,有问题就抛异常。相对于悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。
悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本(Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个"version"字段来实现。
乐观锁的工作原理 :
读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。
配置:
1.在数据库表中加一个字段version
如果是数据库后加的version字段,那么实体类中必须要加上version并生成get、set方法
public class Info implements java.io.Serializable { private String code; private Nation nation; private String name; private Boolean sex; private Date birthday; private Set families = new HashSet(0); private Set works = new HashSet(0); private int version;//实体类中也要有version,并生成getter和setter public int getVersion() { return version; } public void setVersion(int version) { this.version = version; }
2.在映谢文件中配置<version> 这里注意version的位置,一定是要放置在id的后面
<?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">
<!-- Generated 2017-3-11 10:12:32 by Hibernate Tools 5.2.0.CR1 -->
<hibernate-mapping>
<class name="com.itnba.maya.model.Info" table="info" catalog="mydb" optimistic-lock="version">
<cache usage="read-only"/>
<id name="code" type="string">
<column name="Code" length="50" />
<generator class="assigned" />
</id>
<!-- 配置version,位置放在<id></id>下面 -->
<version name="version"></version>
<many-to-one name="nation" class="com.itnba.maya.model.Nation" fetch="select">
<column name="Nation" length="50" />
</many-to-one>
<property name="name" type="string">
<column name="Name" length="50" />
</property>
<property name="sex" type="java.lang.Boolean">
<column name="Sex" />
</property>
<property name="birthday" type="timestamp">
<column name="Birthday" length="19" />
</property>
</class>
</hibernate-mapping>
配置完成后代码不用改变
由乐观锁引发的问题