本帖最后由 bfc99 于 2015-7-6 11:08 编辑

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 oracle 乐观锁,oracle为什么默认乐观锁相关推荐

  1. JAVA——以ReentrantLock为例学习重入锁以及公平性问题

    关注微信公众号:CodingTechWork,一起学习交流进步. 引言   重入锁,顾名思义在于这个重字.开发过程中,我们在用到锁时,可能会用于递归的方法上加锁,此时,那同一个方法对象去重复加锁,是怎 ...

  2. java 对变量加锁_Java最全锁剖析:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁...

    乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度,在Java和数据库中都有此概念对应的实际应用. 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会 ...

  3. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等...

    http://blog.51cto.com/13919357/2339446 Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容 ...

  4. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等

    Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁 / 非公平锁 可重入锁 / 不可重入锁 独享锁 / 共享锁 互 ...

  5. java中的锁(悲观锁、乐观锁、可重入锁、不可重入锁、公平锁、非公平锁、自旋锁、阻塞锁...)

    Lock接口 1.简介.地位.作用 ① 锁是一种工具,用于控制对共享资源的访问 ② Lock和synchronized,这两个是最常见的锁,它们都可以达到线程安全的目的,但是在使用和功能上又有较大的不 ...

  6. Java中的锁机制 -- 乐观锁、悲观锁、自旋锁、可重入锁、读写锁、公平锁、非公平锁、共享锁、独占锁、重量级锁、轻量级锁、偏向锁、分段锁、互斥锁、同步锁、死锁、锁粗化、锁消除

    文章目录 1. Java中的锁机制 1.1 乐观锁 1.2 悲观锁 1.3 自旋锁 1.4 可重入锁(递归锁) 1.5 读写锁 1.6 公平锁 1.7 非公平锁 1.8 共享锁 1.9 独占锁 1.1 ...

  7. java+oracle数据库锁,数据库学习之Oracle数据库\记录被另一个用户锁住\解决方法...

    1.先来看看为什么会出锁住: 数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数 ...

  8. java中乐观锁_java中的乐观锁的研究总结

    前段时间有人问我java中的乐观锁和悲观锁的问题,我被问愣神了,乐观锁和悲观锁我到是听说过,在数据库里面应用极广,但是java里面就好像没有听说过,后来我详细去看了下<java编程思想>, ...

  9. Java多线程锁技术漫谈:乐观锁VS悲观锁

    Java多线程技术一直是Java程序员必备的核心技能之一.在Java多线程编程中,为了保证数据的一致性和安全性,常常需要使用锁的机制来防止多个线程同时修改同一个共享资源.锁是实现并发访问控制的一种机制 ...

最新文章

  1. 少走弯路的10条忠告
  2. 程序员该如何抉择公司?
  3. Web3.js 0.20.x API 中文版翻译
  4. 如何用python画爱心型线_python怎么画爱心
  5. PaddleOCR加载chinese_ocr_db_crnn_modile模型进行中英文混合预测(Http服务)实践
  6. MySQL-索引优化篇(1)_安装演示库 [前缀索引、联合索引、覆盖索引] explain参数
  7. 当Tomcat遇上Netty,我这一系列神操作,同事看了拍手叫绝
  8. 中科大 计算机网络9 互联网历史
  9. 进程同步(multiprocess.Lock、multiprocess.Semaphore、multiprocess.Event) day38
  10. bzoj2127 happiness 最小割
  11. ZABBIX自动发现Redis端口并监控
  12. Helm 3 完整教程(十三):Helm 函数讲解(7)列表函数
  13. 【动态规划 回文串11】LeetCode 516. Longest Palindromic Subsequence
  14. 阶段1 语言基础+高级_1-3-Java语言高级_09-基础加强_第3节 注解_18_注解_案例_简单的测试框架...
  15. mac编写python_刚到手Mac写Python的一个简单问题
  16. 局域网交换机(Lan Switch)
  17. bos物流项目面试问题汇总
  18. SEO–关于如何通过利用流量精灵刷百度排名及排名原理~
  19. 通过命令行清理360安全卫士批处理
  20. 使用express-jwt第三方包报错TypeError: expressJWT is not a function

热门文章

  1. ACM-ICPC 2018 焦作赛区网络预赛
  2. python——LeetCode刷题
  3. android的线程管理器,[Android开源]:一款安全、轻巧、简单的线程池管理器EasyThread...
  4. 华为鸿蒙harmonyos-面向全场,华为正式官宣鸿蒙手机版相约6月2日,EMUI官博更名为HarmonyOS...
  5. qt能使用logback_SpringBoot 中使用 LogBack 配置
  6. 网易2022秋季校园招聘-通用技术A卷-0918
  7. Vue + Element UI + Spring Boot——易班优课YOOC课群在线测试自动答题解决方案(十)问题管理页面
  8. Swagger 2——异常[Illegal DefaultValue null for parameter type integer]解决方案
  9. 2019牛客暑期多校训练营(第九场)
  10. Twitter的分布式自增ID算法Snowflake实现分析及其Java、Php和Python版