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 储户帐号=储户甲的银行帐号;
那么,即使是在乐观锁策略的情况下,依然可以保证数据的正确性和完整性。

---引自 http://www.itpub.net/forum.php?mod=viewthread&tid=1928001

Oracle的悲观锁和乐观锁---摘抄的更多相关文章

  1. Oracle数据库悲观锁与乐观锁详解

    数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住.而乐 ...

  2. Oracle的悲观锁和乐观锁

    为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突.为了解决这个问题,大多数数据库用的方法就是数据的锁定. 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫 ...

  3. (转载)Oracle的悲观锁和乐观锁

    为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突.为了解决这个问题,大多数数据库用的方法就是数据的锁定. 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫 ...

  4. mysql的锁--行锁,表锁,乐观锁,悲观锁

    一 引言--为什么mysql提供了锁 最近看到了mysql有行锁和表锁两个概念,越想越疑惑.为什么mysql要提供锁机制,而且这种机制不是一个摆设,还有很多人在用.在现代数据库里几乎有事务机制,aci ...

  5. MySQL学习笔记(四)悲观锁与乐观锁

    恼骚 最近在搞并发的问题,订单的异步通知和主动查询会存在并发的问题,用到了Mysql数据库的 for update 锁 在TP5直接通过lock(true),用于数据库的锁机制 Db::name('p ...

  6. 关于MySql悲观锁与乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍. 悲观锁(Pessimistic Lock) 悲观锁的 ...

  7. 【MySQL锁】MySQL悲观锁和乐观锁概念

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍. 悲观锁(Pessimistic Lock) 悲观锁的 ...

  8. Sping框架的IOC特性 悲观锁、乐观锁 Spring的AOP特性

    Sping框架的IOC特性 IOC(Inversion of Control):控制反转 以下以课程与老师的安排来介绍控制反转. 一个合理的课程编排系统应该围绕培训的内容为核心,而不应该以具体的培训老 ...

  9. 悲观锁 vs 乐观锁 vs Redis

    企业面对高并发场景采用的方案. 比如 产品抢购高并发时的超发现象. 1 悲观锁悲观锁 需要数据库本身提供支持(Oracle和MySQL都是支持的).实现细节:当前 数据库事务 读取到产品后, 就将目标 ...

  10. mysql行锁、表锁。乐观锁,悲观锁

    锁定用于确保事务完整性和数据库一致性. 锁定可以防止用户读取其他用户正在更改的数据,并防止多个用户同时更改相同的数据. 如果不使用锁定,数据库中的数据可能在逻辑上变得不正确,而针对这些数据进行查询可能 ...

随机推荐

  1. (转)深入理解PHP之数组(遍历顺序)

    深入理解PHP之数组(遍历顺序)(转) http://www.laruence.com/2009/08/23/1065.html (鸟哥) 经常会有人问我, PHP的数组, 如果用foreach来访问 ...

  2. Ubuntu下修改hosts文件

    Ubuntu系统的Hosts只需修改/etc/hosts文件,修改完之后要重启网络.具体过程如下:1.修改hostssudo gedit /etc/hosts2.添加解析记录( . )或者从githu ...

  3. HTTP学习笔记(2)HTTP报文

    1,什么是http报文? 上一节我们了解到数据在浏览器和服务器之间进程传送,这些数据被称为报文流,报文流有流入流出之分,当然在也有上游和下游,这些都是来确定报文的流向. 报文的流向都是向下,而不会回流 ...

  4. Windows 8.1 应用再出发 - 磁贴的更新

    本篇和大家一起了解一下Windows 8.1 中磁贴的更新,我们来看看如何利用它做出更好的应用磁贴. 首先我们从展现形式上来对比一下Windows 8 与 Windows 8.1 中的磁贴: Wind ...

  5. 2.1 View的绘制

    view绘制流程是从ViewRoot的performTraversals()方法中开始的,在该方法中会执行view绘制的三部曲,即:measure(测量视图的大小),layout(确定视图的位置)dr ...

  6. git clone 错误ca-certificates.crt

    git clone https://github.com/baoyiluo/selfblog.git Cloning into 'selfblog'... error: server certific ...

  7. URAL - 1917 Titan Ruins: Deadly Accuracy(水题)

    水题一个,代码挫了一下: 题意不好理解. 你去一个洞窟内探险,洞窟内有许多宝石,但都有魔法守护,你需要用魔法将它们打下来. 每个宝石都有自己的防御等级,当你的魔法超过它的防御等级时它就会被你打下来. ...

  8. 用mysql时遇到的一些问题

    1 mysql5.7文件夹中没有my.ini文件 解决办法-> 如果是windows的系统下安装的,应该是在这个目录下面:C:\ProgramData\MySQL\MySQL Server 5. ...

  9. requests发送HTTP请求

    requests库是一个流行的用于发送Http请求的Python第三方库, 其设计简洁高效可以完美替代默认的urllib. 使用pip安装requests: pip install requests ...

  10. 自己动手写客户端UI库——事件机制(设计思路大放送)

    在上一篇文章中我们创建了一个Button控件,并把这个控件显示在界面上, 在这一篇文章中,我们将为这个控件增加一个事件和一个方法 一:怎么绑定事件的问题 在Winform中,我们对一个按钮绑定事件的方 ...