hibernate锁机制
业务实现过程中,难免需要保证数据访问的排他性。如金融系统的日终结算中,我们会针对某个截止点的数据进行处理,在此同时,不希望在结算的这段时间里(几秒钟或者几个钟头),数据再有变动,不然我们的统计也无效了。这种时候,我们为了保证某些数据在某个操作中不被外界修改,就引入了我们hibernate的锁机制,一旦我们给目标上锁,其他程序则不能去修改。hibernate中锁是两种,悲观和乐观锁。、
悲观锁,自然,它指的是对数据被外界(包括本系统当前的其他事物,以及来自外部系统的事务处理)修改,保持保守态度,因此整个处理过程中,数据一致处于被锁定的状态【额....还真是够悲观的..】,悲观锁的实现,往往依靠数据提供的锁机制(也只有数据库层提供的锁机制,才能真正保证排他性,否则本系统中实现加锁机制,并不能一定保证外部系统不会修改数据)。
下面,这是一个典型的,依赖数据库实现的悲观锁的调用:
Criteria ct=session.createCriteria(User.class); ct.add(Expression.eq("name","Erica")); List userList=ct.list(); User user=(User)userList.get(0); Transaction tx=session.beginTransaction(); user.setUserType(1)'; //更新UserType字段为1 tx.commit();
Criteria ct=session.createCriteria(User.class); ct.add(Expression.eq("name","Erica")); List userList=ct.list(); User user=(User)userList.get(0); Transaction tx=session.beginTransaction(); user.setUserType(1)'; //更新UserType字段为1 tx.commit();
每次去更新的时候,我们可以发现,数据库的version一直在加1。如果我们在tx.commit之前,再启动一个session去对Erica进行更新,以模拟并发更新的话,那么代码就是这样的:
Session session=getSession(); Criteria ct=session.createCriteria(User.class); ct.add(Expression.eq("name","Erica")); Session session2=getSession(); Criteria ct2=session.createCriteria(User.class); ct.add(Expression.eq("name","Erica")); List list1=ct.list(); List list2=ct2.list(); User user1=(User)list1.get(0); User user2=(User)list2.get(0); Transaction tx1=session.beginTransaction(); Transaction tx2=session2.beginTransaction(); user2.setUserType(99); tx2.commit(); user2.setUserType(1); tx1.commit();
Session session=getSession(); Criteria ct=session.createCriteria(User.class); ct.add(Expression.eq("name","Erica")); Session session2=getSession(); Criteria ct2=session.createCriteria(User.class); ct.add(Expression.eq("name","Erica")); List list1=ct.list(); List list2=ct2.list(); User user1=(User)list1.get(0); User user2=(User)list2.get(0); Transaction tx1=session.beginTransaction(); Transaction tx2=session2.beginTransaction(); user2.setUserType(99); tx2.commit(); user2.setUserType(1); tx1.commit();
那么,这段代码执行时会在tx1.commit()处,抛出StaleObjectStateException异常,指出版本检查失败,通过这个异常,我们就可以进行相应的处理。
到这里,假使看的认真的话,我们大概可以知道下面这几点,第一,hibernate锁是用来做什么的一般用于哪些场合或者系统;第二,什么是悲观锁,乐观锁,它们的机制是怎么样的。第三,基础的一些悲观锁乐观锁的使用方法和实际能解决的问题。希望我说的这三点,大家都能有所苟同。