`
esffor
  • 浏览: 1367429 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate悲观锁定与乐观锁定区别

阅读更多
为了避免丢失更新,要使用某种锁定策略,共有两种锁定策略:悲观锁定或乐观锁定。

悲观锁定(pessimistic locking):
用户在屏幕上修改值之前,这个锁定方法就要起作用。例如,用户一旦有意对他选择的某个特定行(屏幕上可见)执行更新,如单击屏幕上的一个按钮,就会放上一个锁。

悲观锁定仅用于有状态(stateful)或有连接(connected)的环境,这是20世纪90年代中期客户/服务器应用中的一种流行做法。但现在采用有状态方式的连接方法已经不太常见了(不过并没有完全消失),特别是随着20世纪90年代中后期应用服务器的出现,有状态连接更是少见。

悲观锁定的例子:
select empno, ename, sal
from emp
where empno = :empno
  and ename = :aname
  and sal = :sal
  for update nowait

乐观锁定(optimistic locking)
即把所有锁定都延迟到即将执行更新之前才作。换句话说,我们会修改屏幕上的信息而不要锁。我们很乐观,认为数据不会被其他用户修改;因此,会等到最后一刻才会去看我们的想法对不对。

这种锁定方法在所有环境下都行得通,但是执行更新的用户“失败”的可能性会增大。这个用户要更新它的数据行时,发现数据已经修改过,所以他必须重头再来。

可以在应用中同时保留旧值和新值,然后在更新数据库时使用如下的更新语句,这是乐观锁定的一种流行实现:
updtae table
  set column1 = :new_column1, column2 = :new_column2,...
where primary_key = :primary_key
  and column1 = :old_column1
  and column2 = :old_column2
   ...

这种情况下,我们可能很幸运地更新了一行,但如果另一个人已经修改了数据,我们就会失败。现在我们必须确定下一步要做什么,是让最终用户重新查询这一行现在的新值,然后再重新开始新事物呢(但是这一行有可能又被修改了,这可能会使用户很受打击)?还是根据业务规则更新冲突,试图合并两个更新的值(这需要大量的代码)?

另外,上面的update有可能被阻塞。如果所有应用(会话)都使用乐观锁定,执行更新并提交时,行只会被锁定很短的时间。但如果某些应用使用了悲观锁定,它会在较长时间内持有行上的锁,你可能就会考虑使用select for update nowait,以此来验证行是否被修改,并在即将update之前锁定来避免被另一个会话阻塞。

另外三种实现乐观并发控制的方法:

1、使用版本列的乐观锁定。
对每个要保护的表增加一列,这一列通常是number或date/timestamp列,通常通过行触发器来维护。
在应用中只需保存这个版本列的值,而不用保存所有其他列的值。
为了维护这个版本列,建议把更新逻辑封装到一个存储过程中。另一个实现方法是使用触发器,但是触发器会引入大量开销。

2、使用校验和的乐观锁定
这与前面的版本列方法很相似,在此要使用计数据本身来计算一个“虚拟的”版本列。有很多方法计算散列或校验和。以下是其中的三种:
·OWA_OPT_LOCK.CHECKSUM:(Oracle8.1.5)及以上版本中提供,出现冲突的可能性是1/65536。
·DBMS_DBFUSCATION_TOOLKIT.MD5:(Oracle8.1.7)及以上版本中提供,出现冲突的可能性是1/(3.4E+38),非常小。
·DBMS_CRYPTO.HSAH:(Oracle10.1)及以上版本中提供.
很多编成语言中都提供了一些散列和校验和函数,所以还可以使用数据库之外的散列和校验和函数。
计算散列和校验和是CPU密集型的操作,其计算代价很昂贵,但是其“网络友好性比较好”。

下面的ORA_ROWSCN方法不仅很小(类似于散列),而且计算时不是cpu密集的。
3、使用ORA_ROWSCN的乐观锁定
从Oracle 10.1开始,你还可以使用内置的ORA_ROWSCN函数,其原理与版本列技术很相似,但是可以由Oracle自动执行,而不需要在表中增加额外的列,也不需要额外的代码来更新维护这个值。

 不管是悲观锁定还是乐观锁定都可以利用select for update nowaut查询来验证行未被修改。悲观锁定会在用户有意修改数据那一刻使用这条语句。乐观锁定则在即将在数据库中更新数据时使用这条语句。这样不仅能解决应用中的阻塞问题,还可以修正数据完整性问题。



 

分享到:
评论

相关推荐

    Hibernate悲观锁和乐观锁的实现

    悲观锁和乐观锁是两种常见的锁定策略,它们各有特点,适用于不同的场景。 **悲观锁**(Pessimistic Lock)的名字来源于其悲观的态度,它认为数据随时可能被其他事务修改,因此在读取数据时就立即进行加锁,防止其他...

    Hibernate悲观锁与乐观锁

    《Hibernate 悲观锁与乐观锁详解》 在多用户并发访问的环境中,数据库管理系统必须具备有效的数据访问控制机制,以确保数据的一致性和完整性。Hibernate,作为一款流行的Java持久化框架,提供了两种主要的锁定策略...

    Hibernate悲观锁与乐观锁案例

    在Java的持久化框架Hibernate中,悲观锁和乐观锁是两种重要的并发控制策略,它们用于管理数据库中的数据在多线程环境下的访问安全。本文将深入探讨这两种锁机制的原理、应用场景及其区别。 首先,我们来理解悲观锁...

    数据库事务、hibernate悲观锁和乐观锁

    在处理并发问题时,Hibernate提供了悲观锁和乐观锁两种机制。 悲观锁假设并发环境中的冲突是常态,因此在读取数据时就立即锁定,直到事务结束才释放。在Hibernate中,可以通过设置`@LockModeType.PESSIMISTIC_READ`...

    Hibernate的乐观锁与悲观锁

    ### Hibernate的乐观锁与悲观锁 #### 一、引言 在并发环境下,尤其是在金融、电商等业务场景中,确保数据的一致性和完整性至关重要。**Hibernate**作为一种流行的Java持久层框架,提供了多种机制来处理并发控制...

    Hibernate乐观锁和悲观锁分析

    【Hibernate乐观锁与悲观锁详解】 在开发过程中,尤其是在并发环境下,确保数据的一致性和完整性至关重要。Hibernate,作为Java领域广泛使用的ORM框架,提供了一种处理并发数据访问冲突的手段,那就是锁机制。主要...

    Hibernate锁机制_悲观锁和乐观锁

    Hibernate 锁机制_悲观锁和乐观锁 Hibernate 锁机制是指在... Hibernate 的锁机制可以分为悲观锁和乐观锁两种,悲观锁通过数据库层次的锁定来实现,而乐观锁通过应用程序上的逻辑实现版本控制的方法来维护正确的数据。

    hibernate乐观锁和悲观锁学习

    与悲观锁不同,乐观锁假设并发环境下数据不会被同时修改,因此在读取数据时不会立即加锁。只有在更新数据时,才会检查数据是否自上次读取后发生了变化。在Hibernate中,通常通过在实体类的映射文件中设置`optimistic...

    hibernate的乐观锁和悲观锁

    ### Hibernate的乐观锁和悲观锁 #### 一、引言 在软件开发中,尤其是在涉及大量并发操作的应用场景下,确保数据的一致性和完整性是非常重要的。对于基于Java Web的应用而言,Hibernate作为一款流行的ORM框架,提供...

    Java 中的悲观锁和乐观锁的实现

    乐观锁与悲观锁相反,它假定数据不太可能被其他线程或进程修改,因此不会一开始就锁定数据。这种锁机制通常不会直接使用数据库级别的锁定机制,而是通过版本号或其他标记来检测数据是否已被其他事务修改。 **1. ...

    Hibernate 乐观和悲观锁

    6. **文件关联**:压缩包中的文件名称列表看似与主题“Hibernate 乐观和悲观锁”不直接相关,"走出软件作坊:三五个人十来条枪 如何成为开发正规军.chm、走出软件作坊.doc"可能是一些关于软件开发团队建设和成长的...

    Hibernate性能(缓存 延迟加载 事务 悲观 乐观锁).ppt

    缓存、延迟加载、事务管理和锁定策略是提升Hibernate性能的四大关键要素。 **1. Hibernate缓存** 缓存机制是提高ORM框架性能的核心,它减少了对数据库的直接访问,从而提升了数据读取速度。Hibernate提供了三级缓存...

    Hibernate乐观锁

    在乐观锁的机制下,假设并发用户很少会发生冲突,所以在读取数据时不会进行任何锁定,而在更新数据时才会检查在此期间是否有其他用户修改过该数据。如果检测到有其他用户修改,更新操作将会失败,通常会抛出一个异常...

    Hibernate电子书(全)

    Hibernate提供了悲观锁定和乐观锁定两种机制,用于在并发环境下保护数据的一致性。悲观锁定在操作数据前会加锁,而乐观锁定则是在数据更新时检查版本信息,以决定是否需要回滚。 #### SchemaExportTask与Hbm2Java...

    hibernate事务管理机制.doc

    **悲观锁**是预防性的锁定策略,它假设并发环境中多线程可能会同时修改同一数据,因此在读取数据时就对其进行锁定,直至事务结束才释放。在Hibernate中,悲观锁可以通过`LockMode`进行设置,如`LockMode.WRITE`、`...

    Hibernate4实战 之第五部分:Hibernate的事务和并发

    ### Hibernate4实战之第五部分:Hibernate的事务与并发 #### 一、事务基础概念 **事务(Transaction)** 是一组逻辑上紧密相连的操作集合。在数据库领域,事务具备ACID特性: - **原子性(Atomicity)**:事务内的所有...

    Hibernate.lock()方法中各种锁的区别.docx

    **悲观锁**(Pessimistic Lock)与**乐观锁**(Optimistic Lock)是数据库和对象关系映射(ORM)框架中两种重要的锁定机制,主要用于解决并发控制问题。 ##### 悲观锁 悲观锁假设数据会被频繁地并发访问和修改,...

    Hibernate 事务和并发控制

    Hibernate提供了一些策略来解决这些问题,包括乐观锁和悲观锁。 乐观锁假设并发冲突很少发生,通常在数据更新时检查版本号或时间戳,如果发现有其他事务在此期间修改了数据,就回滚事务。在Hibernate中,可以通过在...

Global site tag (gtag.js) - Google Analytics