`
andymu1117
  • 浏览: 36729 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

Hibernate的悲观锁与乐观锁

阅读更多

悲观锁:在应用程序中显式为数据资源加锁。悲观锁假定当前事务操纵数据资源时,肯定还会有其他事务访问该资源,为了避免当前事务的操作受干扰,先锁定资源,它能防止丢失更新和不可重复读等并发问题,但会影响并发性能。
   乐观锁:假定当前事务操纵数据资源时,不会有其他事务同时访问该数据资源,因此完全依靠数据库的隔离级别来自动管理锁的工作。

悲观锁有两种实现方式
    方式一:在应用程序中显式指定采用数据库系统的独占锁来锁定数据源。
    方式二:在数据库表中添加记录状态的LOCK字段,取值"Y","N",分别表示被锁定与空闲状态。

  
    select ... for update 显式指定采用独占锁查询记录。执行事务持有锁,直到事务结束释放锁。在Hibernate中,当通过Session的get()和Load()加载一个对象时,采用
  session.get(Account.class,new Long(1),LockMode.UPGRADE); 声明使用悲观锁
  锁定模式LockMode
  LockMode.NONE 默认值 如果缓存中存在对象,直接返回引用,否则通过select到数据库中加载对象。
  LockMode.READ 不管是否存在对象,总是通过select到数据库中加载对象。
  LockMode.UPGRADE 不管是否存在对象,总是通过select到数据库中加载对象。如果数据库系统支持悲观锁(如ORACLE与MYSQL),就执行select ... for update。如果不支持,就执行普通的select语句。
  LockMode.UPGRADE_NOWAIT 同LockMode.UPGRADE相同,此外,对ORACLE数据库,执行select ... for update nowait,表示如果不能立刻获得悲观锁,不等待其他事务释放锁,而是抛出锁定异常。


乐观锁的实现
  方式一:使用<version>元素,在POJO中添加一个代表版本信息的属性version,在数据库表中添加相应字段,在mapping文件中,紧跟<id>元素,添加<version name="version" column="version">在程序中捕获StaleObjectStateException。以后的数据操作中,每次都会自动更新version字段(自动加1)。
  方式二:使用<timestamp>元素,基本与<version>同,POJO中添加属性(这是一个DATE属性),当持久化对象时,Hibernate会用当前的系统时间来为它赋值。
  理论上,<version>比<timestamp>更安全,因为后者只能精确到秒。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics