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锁是用来做什么的一般用于哪些场合或者系统;第二,什么是悲观锁,乐观锁,它们的机制是怎么样的。第三,基础的一些悲观锁乐观锁的使用方法和实际能解决的问题。希望我说的这三点,大家都能有所苟同。

相关推荐