`
hongwei3344661
  • 浏览: 31322 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

ORACLE悲观锁和乐观锁

 
阅读更多

Oracle的悲观锁和乐观锁---摘抄

 

1、无论是选择悲观锁策略,还是乐观锁策略。如果一个对象被上了锁,那么该对象都会受这个锁的控制和影响。


2、选择悲观锁策略,还是乐观锁策略,这主要是由应用和业务需求来确定的。如果你的应用和业务经常会出现从我看到要修改的记录的值,到我修改完成该记录这个时间段内,该记录有较大概率被其它会话所修改。换句话说就是,在我真正去做出修改时,这个记录的值很可能已经与我当初看到的不同了。那么这时,采取悲观锁策略,也许是更好的。而采取悲观锁策略的一个典型操作就是 select ... for undate。通过这种操作,使得从我一开始查看该记录起,这条记录就被上了排它锁,不允许其它会话再对该记录有任何修改。
相对的,如果你的业务和应用基本上很少出现这种情景,那么选择乐观锁策略也许就会更好。

3、这两种策略的核心其实就是持有锁的时间的起止点不同,悲观锁是从读取记录的那一刻就开始了,而乐观锁只从UPDATE那一刻开始;结束的点两者是一样的,都是发出commit或rollback命令。所以,悲观锁策略会使锁的持续时间更长,而乐观锁的持续时间则较短。其影响就是并发。悲观锁的并发性低于乐观锁。

4、无论是采用哪种策略,都要保证数据的完整性。通常情况下,是有可能出现数据的不完整。举例来说:储户甲的存款余额100元,假设在几乎相同的时刻,发生了两笔业务,业务1为其存入了50元,另一个业务是其网上购物消费了30元。显然,这两个操作结束后,甲的存款余额应为120元(100+50-30)。但我们设想一下在数据库层面,可能出现这种情况,当其在银行柜台存入50元时,银行操作员收到了甲存入的50元现金,并通过 select 语句看到甲的当前余额为100元(其发出的指令是下面的语句:
select 余额 
   from 存款余额表
where 储户帐号=储户甲的银行帐号;)

,接着,发出指令 
update 存款余额表
      set 余额=150
    where 储户帐号=储户甲的银行帐号;

但就在其看到甲的余额为100元,到其修改甲的余额为150这期间,甲在网上的消费行为导致交易系统已经将甲的余额变成了70元(100-30)并提交了。当银行员工发出的指令也被提交后,甲的余额变成了150元,相当于甲网上消费的行为没有产生任何扣款。这显然是不正确的,更是要避免出现的。
如果这套系统采用的是悲观锁策略,那么在从银行员工查看甲当前余额的那一个时刻起(这时查询的指令就会是:
select 余额 
   from 存款余额表
where 储户帐号=储户甲的银行帐号 for update;)
该记录就已经被锁定了,这时甲网上消费的行为导致的交易系统从甲的帐户中扣减的操作就会处于等待状态。直至银行员工提交了相关指令,交易系统才能去扣减甲的钱款。这样,就可以确保甲的帐户余额是正确的。
悲观锁的策略显然可以保证业务的正确性和完整性。但再设想一下,如果甲在存款时,银行员工内急,或者储户甲说等一等,我要考虑一下是否再多存一些。那么,银行员工的操作就不会提交,这时网上交易系统对甲帐户的扣款操作就会一直处于等待状态,或者在等待一定时间后,返回一个扣款失败的提示。这对于系统的效率和客户来说,都不是一个好的体验。

5、所以,我们在设计应用时,可以采取一些其它方法来避免上述情况的发生。其思想就是在真正提交时,确认要修改的数据没有变化过。主要的方法如下:
(1)、更新时带入原始的数据。
     update 存款余额表
      set 余额=150
    where 储户帐号=储户甲的银行帐号 and 余额=100;
(2)、在记录上增加修改的时间戳(也可利用ora_rowscn伪列)。即在事务开始时,获取该记录的时间戳,修改时,校验该时间戳,若一致则修改。

6、其实,我上面举的这个例子,如果在业务设计时,选择更新指令为
update 存款余额表
      set 余额=余额+50
    where 储户帐号=储户甲的银行帐号;
那么,即使是在乐观锁策略的情况下,依然可以保证数据的正确性和完整性。

分享到:
评论

相关推荐

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

    悲观锁和乐观锁各有优缺点,选择哪种锁机制取决于具体的应用场景和需求。悲观锁适合数据修改频繁且对数据一致性要求较高的场景;而乐观锁适用于数据修改较少且并发量较大的场景。在实际应用中,可以根据具体情况灵活...

    Hibernate乐观锁和悲观锁分析

    Hibernate支持的悲观锁模式有`LockMode.UPGRADE`(对应SQL的`for update`)和`LockMode.UPGRADE_NOWAIT`(Oracle特有的,用于立即返回等待超时的结果)。 **乐观锁(Optimistic Locking)** 乐观锁则相对乐观,它...

    Hibernate的乐观锁与悲观锁

    **Hibernate**作为一种流行的Java持久层框架,提供了多种机制来处理并发控制问题,其中最常用的就是**乐观锁**和**悲观锁**。本文将详细介绍这两种锁的原理、应用场景以及如何在Hibernate中实现。 #### 二、悲观锁...

    hibernate的乐观锁和悲观锁

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

    hibernate乐观锁和悲观锁学习

    本文主要讨论的是Hibernate框架中两种锁机制的使用:乐观锁和悲观锁。 首先,让我们深入理解悲观锁(Pessimistic Locking)。悲观锁正如其名字所示,假设并发环境中数据会被频繁修改,所以在整个数据处理过程中,它...

    Hibernate实现悲观锁和乐观锁代码介绍

    Hibernate 实现悲观锁和乐观锁代码介绍 Hibernate 是一个基于 Java 的持久层框架,它提供了多种锁机制来实现事务的隔离性和一致性。在本文中,我们将详细介绍 Hibernate 实现悲观锁和乐观锁的代码实现,并讨论 ...

    Oracle的锁机制

    根据锁定时间,锁可分为悲观锁和乐观锁。悲观锁假设数据操作会发生冲突,所以在读取数据时立即锁定,例如表级锁。乐观锁则在数据更新时检查冲突,如行级锁,这样可以提高并发性能。 根据保护的对象,Oracle的锁分为...

    java调用Oracle的锁表命令

    - 考虑使用乐观锁或悲观锁策略,根据应用的并发需求选择合适的方式。 通过以上步骤,你可以在Java程序中安全有效地调用Oracle的锁表命令,确保数据一致性并优化并发性能。对于更复杂的应用场景,如分布式事务,...

    在分布式事务中实现基于Oracle PLSQL UL LOCK的悲观离线锁

    Oracle中的用户级(UL)锁就是一种悲观锁,它允许用户自定义锁机制,提供更细粒度的控制。 PL/SQL UL LOCK的实现通常涉及以下几个步骤: 1. **创建锁表**:首先,你需要创建一个表来存储锁定信息。这个表通常包含...

    查看Oracle锁表

    3. **并发控制机制**:如乐观锁和悲观锁等技术。 4. **定期检查锁定情况**:定期执行上述SQL查询,及时发现并解决锁定问题。 #### 五、总结 在Oracle数据库中,了解和掌握锁定机制对于确保数据完整性和提高系统...

    oracle锁表处理

    - **并发控制**:使用Oracle提供的并发控制机制,如乐观锁或悲观锁。 通过以上方法,可以有效地分析并处理Oracle中的锁争用问题,提高系统的性能和稳定性。需要注意的是,在实际操作中应当谨慎处理锁争用问题,...

    SQL数据库系统原理(二)———乐观锁与悲观锁、MVCC、范式理论、SQL和NoSQL比较

    在数据库系统中,为了保证数据的一致性和完整性,有多种并发控制策略,其中包括乐观锁和悲观锁。这两种锁机制主要用于解决事务在并发环境中的数据冲突问题。 乐观锁是一种假设事务在执行过程中不会发生冲突的策略。...

    ORACLE深入浅出-中级篇.pptx

    悲观锁可以使用 for update nowait 语句来加锁,而乐观锁可以通过增加标识列或使用 Oracle 的 ORA_ROWSCN 机制来实现。 阻塞与死锁 如果两个会话都持有另一个会话想要的资源,就会出现死锁。例如,可以打开两个...

    Oracle表死锁与解锁

    - 在编程时,对可能出现死锁的操作进行预测和处理,例如使用事务的乐观锁或悲观锁策略。 通过理解Oracle表死锁的原理、使用上述检测和解决方法,以及遵循最佳实践,可以有效地管理和防止数据库死锁,保证系统的稳定...

    ORACLE资料ORACLE资料

    乐观锁和悲观锁是常见的并发控制策略,还有行级锁定和多版本并发控制(MVCC)机制。 7. **备份与恢复**:Oracle支持多种备份方式,如物理备份、逻辑备份、RMAN(恢复管理器)备份。了解如何进行数据库恢复,包括闪...

    oracle 锁

    - **乐观锁**:假设很少发生冲突,因此在提交事务时检查是否有冲突,如版本控制或时间戳。 - **悲观锁**:在访问数据时立即锁定,防止其他用户修改,适合高冲突环境。 4. **锁定级别**: - **多粒度锁定...

    oracle锁讲解笔记

    Oracle中的锁主要分为三类:DML锁、DDL锁和内部锁(LATCH)。DML锁又细分为表级锁(TM)和行级锁(TX)。 - **表级锁(TM)**:用于保护表级别的操作,防止DDL语句的执行。 - **行级锁(TX)**:用于保护行级别的...

Global site tag (gtag.js) - Google Analytics