hibernate 锁

       业务实现过程中,难免需要保证数据访问的排他性。如两个事务同时判断条件成立,都进行数据插入的情况,这时我们就需要依赖锁机制来解决这种条件同时成立的情况。Hibernate 支持两种锁机制:悲观锁(Pessimistic Locking);乐观锁(Optimistic Locking);

       另外大家实际上都会有一个疑问,那就是Hibernate不是有隔离级别了吗,为什么还要去使用悲观锁和乐观锁呢,实际上隔离级别不能解决所有的并发问题,除了serial隔离级,但是这种隔离级别下的事务都是串行执行的,并发性得不到保障,一般在生产环境下不会使用,在生产环境下使用的比较多的是read committed和repeate read两种隔离级别。这两种隔离级别解决了一些并发问题,但是对于特殊的场景,还是无能为力的,比如之前说的两个并发事务都判断条件成立了,都进行数据插入的问题,这种情况下read committed和repeate read都没有办法解决问题,我们需要依赖数据库的锁机制。

       所以隔离级别只是在一定程度上解决了数据库事务的并发问题,但是要更灵活的控制事务的并发,就得使用锁机制。

1、悲观锁

       它指的是对数据被外界修改保持保守态度,因些,在整个数据处理过程中,将数据牌锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层的锁机制才能保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

       针对Mysql数据,悲观锁的调用语句,select * from tb ... for update,实际上就是对应于Mysql的排他锁。

       Hibernate中的锁模式有下面几种
       LockMode.NONE:无锁机制
       LockMode.WRITE:Hibernate 在Insert 和Update记录的时候会自动获取
       LockMode.READ:Hibernate在读取记录的时候会自动获取
       以上三种锁机制一般由Hibernate内部使用,如Hibernate为了保证Update过程中对象不会被外界修改,会在save方法实现中自动为目标添加上WRITE锁,这些都是Hibernate内部对数据的锁定机制。
       LockMode.UPGRADE:利用数据库的for update子句
       LockMode.UPGRADE_NOWAIT:Oracle的特定实现,利用Oracle的for update nowait子句实现加锁
       以上二种锁机制是我们在应用层较为常用的,依赖数据库的排他锁机制。

2、乐观锁

       相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制,基于先执行后比较的原则。乐观锁,大多是基于数据版本(Version)记录机制实现,一般是通过为数据库表增加version字段来实现。具体过程为,读取出数据时,将此版本号一同读出,之生更新时,对此版本号加1.此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

       Hibernate 中可以通过class描述符的optimistic-lock属性结合version描述符指定。如下,

       <hibernate-mapping>
            <class name="TbbsUser" table="TBBS_USER" dynamic-update="true" dynamic-insert="true"optimistic-lock="version">

       </hibernate-mapping>

3、总结

       Hibernate悲观锁机制可能会导致死锁的产生,使用Hibernate的悲观锁需要特别注意。另外就是需要知道Hibernate悲观锁什么时候是表锁,什么时候是行锁,这个很重要。

       比如在行锁的情况下,若select得到的是空集合,事务A和事务B有可能同时获得空集合,这样在隔离级别为repeate read下是会导致死锁的,因为两个事务的insert会被阻塞,都等待对方释放锁,这时可以考虑使用read committed隔离级别,这样insert不会阻塞,先insert成功,后insert会由于主键冲突出现异常。

       上面只是举了一个锁导致死锁的例子,目的是要大家再使用悲观锁的时候多多留心,其实我有一点建议就是,若大家对Hibernate的锁机制没有底的时候,可以使用同步的方式来代替,这其实也是一个不错的方法。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值