您的位置:首页 > 其它

【hibernate集锦】---悲观锁和乐观锁

2015-10-30 20:07 253 查看

why?

   

   如下图所示,一天结束后,某商场核算员1和核算员2均要对库存中的奶粉数量重新进行统计。假设库存中原有奶

粉数量为1000,一天内核算员1和核算员2所在分区的销售量均为200,核算员1读取数据并开始计算,此时核算员2也

读取数据开始计算,核算员1统计完后提交数据,库存量变为800。但是核算员2手中持有的基数还是原有库存量

1000,这样一来就对不上账了。。。

   类似这种情况,我们就需要通过一些机制来保证这些数据在某个操作过程中不会被外界修改,也就是所谓

的“锁”,即给我们选定的目标数据上锁,使其无法被其它程序修改。



What?

Hibernate 支持两种锁机制来保证数据访问的排他性:

1. 悲观锁(Pessimistic Locking);

2. 乐观锁(Optimistic Locking);



悲观锁

      

   悲观锁,假定当前事务操纵数据资源时,肯定还会有其它事务同时访问该数据资源,为了避免当前事务的操作受到

干扰,先锁定资源。       

   如上所述,悲观锁对于数据被外界修改保持极端保守态度,当执行一条查询时就要将整个过程中把数据锁住,只

要事务不释放(提交/回滚),那么其他任何用户都不能查看或修改。这一过程,通过在应用程序中显示地为数据资

源加锁和数据库机制相结合实现的。

悲观锁实现

session.beginTransaction();
Inventory inv = (Inventory)session.load(Inventory.class, "1001", LockMode.UPGRADE);
inv.setQuantity(inv.getQuantity() - 200);
session.getTransaction().commit();


   尽管悲观锁能防止丢失更新和不可重复读这类并发问题,但会影响并发性能。悲观锁大多数情况下依靠数据库的锁

机制,以操作最大程度的独占性。但随着而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销系统

往往无法承受。



乐观锁

   乐观锁,假定当前事务操纵数据资源时,不会有其它事务同时访问该数据资源,因此完全依靠数据库的隔离级别来

自动管理锁的工作。

   乐观锁其实不是锁,它只是一种检测冲突的手段。相对悲观锁而言,乐观锁机制采取了宽松的加锁机制,大多是

基于数据版本记录机制或时间戳机制来避免可能出现的并发问题的。

什么是数据版本?

   数据版本,即为数据增加一个版本标识,在基于库表的版本解决方案中,一般是通过为数据库表增加version字段

来实现。在读取数据的时候将version读取出来,在保存数据的时候先判断version的值是否小于数据库中的version

值,如果小于不予更新,否则给予更新。需要注意的是,只有真实修改对象的属性,才会version加1。

   如下图所示,为库存记录添加version标识,当核算员1提交数据后库存标识version版本由0变为1,当核算员2再

次提交时,当前版本号0小于现有库存版本号1,因此不能进行更新操作。



什么是时间戳?

    同理,即为记录添加时间标识。用时间是否相同来判断是否要进行数据库操作。不再做详细介绍。

乐观锁实现

首先需要在实体类中添加version字段

<span style="font-family:SimSun;font-size:18px;">public class Inventory {

private String itemNo;

private String itemName;

private int quantity;
//添加版本号version
private int version;
}
</span>


   在配置文件中配置乐观锁的标识,optimistic-lock="version"。注意,version节点必须出现在ID节点之后。时间

戳同理。

<span style="font-family:SimSun;font-size:18px;"><hibernate-mapping>
<class name="com.mytest.hibernate.Inventory" table="inventory" optimistic-lock="version">
<id name="itemNo">
<generator class="assigned"/>
</id>
<version name="version"/>
<property name="itemName"/>
<property name="quantity"/>
</class>
</hibernate-mapping>
</span>


     相比较而言,不难看出乐观锁更被提倡。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: