Hibernate之悲观锁与乐观锁

来源:互联网 发布:linux运行jar包命令 编辑:程序博客网 时间:2024/05/24 03:53

    所谓的加锁是为了解决程序的高并发访问问题,对一些资源的访问进行控制,加锁的两种方式就分为悲观锁和乐观锁。本篇博客我们一起探索这两种锁之间的关系。

悲观锁:

    悲观锁是由数据库机制实现的,在整个过程中把数据锁住,只要事务不释放(提交或者回滚),任何人都不能查看或者修改数据,只能处于等待状态。

悲观锁的应用非常简单,只需要在sql语句后面加上一个“for update”即可,此sql语句告诉数据库锁定相关的数据。如:Inventoryinv=(Inventory)session.load(Inventory.class,"1001",LockMode.UPGRADE);在使用load方法时,将最后一个参数的LockMode设置为UPGRADE。

    虽然悲观锁的使用在Hibernate中很方便,但是由于数据一旦被锁定,就只能等待释放,如果有用户一直占用资源不释放,那么其他人就永远无法使用该资源,这会造成资源的极大浪费,所以实际应用中很少使用悲观锁,一般使用乐观锁。

乐观锁:

   乐观锁实际是一种冲突检测的方式,采用对数据加上一个版本控制的方式,一般在数据库中加入一个version字段在读取数据的时候讲version读取出来,在保存数据的时候判断version的值是否小于数据库中的version值,如果小于不予更新,否则予以更新。

    Hibernate中对于乐观锁的实现提供了三种方式,一种是增加一个version字段作为版本标识,映射文件中提供了一个optimistic-lock属性。映射文件如下:

<hibernate-mapping><class    name="com.bjpowernode.hibernate.Inventory"table="t_inventory" optimistic-lock="version"><id name="itemNo"><generator class="assigned"/><!-- 设置主键生成策略为手动分配 --></id><version name="version"/><property name="itemName"/><property name="quantity"/></class></hibernate-mapping>

    第二种方式和前面一种思想是一样的,只是把version字段换成了timestamp,采用时间戳的方式完成。

第三种方式基于遗留项目方式,如果数据库中无法添加上面提到的那种字段为本版本控制标识,我们将无法使用上面的两种方式,只能使用这种基于遗留项目的这种方式。在配置文件中设置optimistic-lock="all"。设置dynamic-update="true"。

   映射文件如下:

<hibernate-mapping>      <class  name="com.bjpowernode.hibernate.Inventory"  table="t_inventory" optimistic-lock="all" dynamic-update="true">          <id name="itemNo">              <generator class="assigned"/>          </id>          <!-- <version name="version"/> -->          <!--<timestamp name="updateDate"/> -->          <property name="itemName"/>          <property name="quantity"/>      </class>  </hibernate-mapping>

    Hibernate提供的这两种锁的机制限制了数据库的并发性的操作,保证了数据的完整性,悲观锁对数据库的依赖性很强,在大数据量的操作上会增加数据库的负担,相比之下,实际应用会选择乐观锁。




0 0
原创粉丝点击