Hibernate悲观锁和乐观锁
摘自:https://www.cnblogs.com/coderMark/p/5599508.html
Hibernate支持两种锁机制:
悲观锁和乐观锁
悲观锁,借助数据库的加锁机制,下面的代码实现了对查询记录的加锁:
String hql = "from User where User.name = '小唯'";
Query query = session.createQuery(hql);
query.setLockMode("User",LockMode.UPGRADE);
List list = query.list();
加锁一般通过以下方法实现:
Criteria.setLockMode
Query.setLockMode
Session.lock
乐观锁,大多是基于数据版本(Version)记录机制实现。为数据库表增加version字段实现乐观锁,每次读取数据时,将version一并读出,当修改数据时将version值加一,然后与数据库中的version对比,如果比数据库表的version值大,则予以更新,否则不更新。实现步骤:
1.在需要添加乐观锁的映射文件中class标签添加:optimistic - lock = " version " ;
2.接下来在对应映射文件class标签下添加version属性描述:<version column="version" name="version",type="java.lang.Integer"/>,此version标签必须仅次于id标签;
悲观锁与乐观锁的比较:
悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受;
乐观锁机制采取了更加宽松的加锁机制。乐观锁机制往往基于系统中的数据存储逻辑,因此也具备一定的局限性,如在上例中,由于乐观锁机制是在我们的系统中实现,来自外部系统的更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。在
系统设计阶段,我们应该充分考虑到这些情况出现的可能性,并进行相应调整(如将乐观锁策略在数据库存储过程中实现,对外只开放基于此存储过程的数据更新途径,而不是将数据库表直接对外公开)。
Hibernate 在其数据访问引擎中内置了乐观锁实现。如果不用考虑外部系统对数据库的更新操作,利用Hibernate提供的透明化乐观锁实现,将大大提升我们的生产力。
Hibernate中可以通过class描述符的optimistic-lock属性结合version描述符指定。
通过version实现的乐观锁机制是Hibernate官方推荐的乐观锁实现,同时也是Hibernate中,目前唯一在数据对象脱离Session 发生修改的情况下依然有效的锁机制。因此,一般情况下,我们都选择version方式作为Hibernate乐观锁实现机制。