一、问题引出

1. 假设当当网上用户下单买了本书,这时数据库中有条订单号为001的订单,其中有个status字段是’有效’,表示该订单是有效的;

2. 后台管理人员查询到这条001的订单,并且看到状态是有效的;

3. 用户发现下单的时候下错了,于是撤销订单,假设运行这样一条SQL: update order_table set status = ‘取消’ where order_id = 001;

4. 后台管理人员由于在②这步看到状态有效的,这时,虽然用户在③这步已经撤销了订单,可是管理人员并未刷新界面,看到的订单状态还是有效的,于是点击”发货”按钮,将该订单发到物流部门,同时运行类似如下SQL,将订单状态改成已发货:update order_table set status = ‘已发货’ where order_id = 001;

那么如何解决该问题呢?

二、悲观锁

所谓的悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次拿数据的时候都会上锁。这样别人拿数据的时候就要等待直到锁的释放。

Oracle的悲观锁需要利用一条现有的Connection,它分成两种方式,从SQL语句的区别来看,就是一种是select for update,一种是select for update nowait的形式。

1. 执行select xxx for update操作时,数据会被锁定,只有执行comit或rollover才会释放

2. 执行select xxx for update nowait操作时,数据也会被锁定,其他人访问时或返回ORA-00054错误,内容是资源正忙,需要采取相应的业务措施进行处理。

虽然悲观锁应用起来很简单并且十分安全,与此同时也有两个问题:

1. 锁定:应用的使用者选择一个记录进行更新,然后去吃午饭,但是没有结束或者丢弃该事务。这样其他所有需要更新该记录的用户就必须等待正在进行实务操作的用户回来并且完成该事务或者直到DBA杀掉该不愉快的事务并且释放锁。

2. 死锁:用户A和B同时更新数据库。用户A锁定了一条记录并且试图请求用户B持有的锁,同时用户B也在等待获取用户A持有的锁。两个事务同时进入了无限等待状态即进入死锁状态。
三、乐观锁

所谓的乐观锁:就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。oracle默认使用乐观锁

1. 第一种就是在数据取得的时候把整个数据都copy到应用中,在进行提交的时候比对当前数据库中的数据和开始的时候更新前取得的数据。当发现两个数据一模一样以后,就表示没有冲突可以提交,否则则是并发冲突,需要去用业务逻辑进行解决。

2. 第二种乐观锁的做法就是采用版本戳,这个在Hibernate中得到了使用。采用版本戳的话,首先需要在你有乐观锁的数据库table上建立一个新的column,比如为number型,当你数据每更新一次的时候,版本数就会往上增加1。比如同样有2个session同样对某条数据进行操作。两者都取到当前的数据的版本号为1,当第一个session进行数据更新后,在提交的时候查看到当前数据的版本还为1,和自己一开始取到的版本相同。就正式提交,然后把版本号增加1,这个时候当前数据的版本为2。当第二个session也更新了数据提交的时候,发现数据库中版本为2,和一开始这个session取到的版本号不一致,就知道别人更新过此条数据,这个时候再进行业务处理,比如整个Transaction都Rollback等等操作。在用版本戳的时候,可以在应用程序侧使用版本戳的验证,也可以在数据库侧采用Trigger(触发器)来进行验证。不过数据库的Trigger的性能开销还是比较的大,所以能在应用侧进行验证的话还是推荐不用Trigger。

3. 第三种做法和第二种做法有点类似,就是也新增一个Table的Column,不过这次这个column是采用timestamp型,存储数据最后更新的时间。在Oracle9i以后可以采用新的数据类型,也就是timestamp with time zone类型来做时间戳。这种Timestamp的数据精度在Oracle的时间类型中是最高的,精确到微秒(还没与到纳秒的级别),一般来说,加上数据库处理时间和人的思考动作时间,微秒级别是非常非常够了,其实只要精确到毫秒甚至秒都应该没有什么问题。和刚才的版本戳类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。如果不想把代码写在程序中或者由于别的原因无法把代码写在现有的程序中,也可以把这个时间戳乐观锁逻辑写在Trigger或者存储过程中。

四、结论

1. 如果系统并发量不大且不允许脏读,可以使用悲观锁解决并发问题。

2. 如果系统并发非常大的话,悲观锁会带来很大性能问题,所以一般采用乐观锁。

3. 如果系统读比较多,写比较少,也应该使用乐观锁,可以提高吞吐量。

转载于:https://www.cnblogs.com/smellpawn/p/10799345.html

oracle的乐观锁和悲观锁相关推荐

  1. oracle数据库字段的值加一_天天面试--数据库乐观锁和悲观锁

    悲观锁 悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.悲观锁:假 ...

  2. 乐观锁与悲观锁深入学习

    在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲 ...

  3. 独占锁、共享锁、更新锁,乐观锁、悲观锁

    转载自   独占锁.共享锁.更新锁,乐观锁.悲观锁 1.锁的两种分类方式 (1)从数据库系统的角度来看,锁分为以下三种类型: 独占锁(Exclusive Lock)       独占锁锁定的资源只允许 ...

  4. 乐观锁与悲观锁及其实现

    乐观锁与悲观锁及其实现 乐观锁  每次操作时不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止 悲观锁  是会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁. 乐观锁可 ...

  5. mysql行锁还需要乐观锁吗_mysql行锁、表锁。乐观锁,悲观锁

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

  6. 浅谈实现数据库乐观锁和悲观锁

    目录 数据库乐观锁 适用场景 定义 实现方式 优点与缺点分析 优点 缺点 案例 数据库悲观锁 适用场景 定义 实现方式 悲观锁优缺点分析 优点 缺点 在单实例JVM中,常见的处理并发问题的方法有很多, ...

  7. mysql悲观锁和乐观优缺点_乐观锁、悲观锁和MVCC各是什么?各自优缺点是什么?...

    在数据库的实际使用过程中,我们常常会遇到不希望数据被同时写或者读的情景,例如秒杀场景下,两个请求同时读到系统还有库存1个,然后又先后把库存更新为0,这时候就会出现超卖的情况,这时候货物的实际库存和我们 ...

  8. Hibernate乐观锁和悲观锁详解

    悲观锁: 悲观锁是对数据库而言的,数据库悲观了,他感觉每一个对他操作的程序都有可能产生并发.它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据 ...

  9. 数据库的锁机制(悲观锁/乐观锁)

    在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲 ...

  10. [初级]深入理解乐观锁与悲观锁

    2019独角兽企业重金招聘Python工程师标准>>> 在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔 ...

最新文章

  1. 服务器比普通电脑响应速度快吗,云服务器比普通的快吗
  2. IDC:以太网交换机市场增长2%
  3. Cypress 里的 ensureAttached 检测原理
  4. 别再双塔了!谷歌提出DSI索引,检索效果吊打双塔,零样本超BM25!
  5. layui表格使用:经验总结(含案例、代码、截图)
  6. 解决nginx下connect() to 127.0.0.1:3000 failed
  7. JS箭头函数的优势在哪里
  8. Python开源项目大集合:15个领域,181个项目 | 硬核干货
  9. JPA与EJB3的关系
  10. Windows应用商店下载安装Ubuntu
  11. 详细设计的工具——程序流程图
  12. 新会计准则与旧版内容的不同比较
  13. 测度论与概率论基础学习笔记7——3.1积分的定义
  14. 【BZOJ2813】奇妙的Fibonacci(结论,线性筛)
  15. js制作网页动态背景
  16. 使用html5与js实现音乐播放器
  17. android添加侧滑菜单,Android侧滑菜单控件DrawerLayout使用详解
  18. 葡萄糖氧化酶(GOD)修饰纳米金(Nano-Au)/壳聚糖(CS)/1-丁基-3-甲基咪唑六氟磷酸盐(BMIMPF6)复合材料
  19. 【地图学】地图投影的定义和分类
  20. 数据结构 图(一)丛林中的路

热门文章

  1. codewars068 - Convert string to camel case
  2. linux shell之cut用法
  3. web前端研发工程师编程能力成长之路
  4. BUZZER Driver
  5. asp.net面试的代码题目
  6. Django-Ajax
  7. 快速书写常见的 Kotlin 代码 MD
  8. 【翻译】《理解收益率曲线》系列
  9. 洛谷P2896 [USACO08FEB]一起吃饭Eating Together
  10. 关于CRTP(Curiously Recurring Template Prattern)的使用