悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。

两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。

本质上,数据库的乐观锁做法和悲观锁做法主要就是解决下面假设的场景,避免丢失更新问题:
        一个比较清楚的场景
        下面这个假设的实际场景可以比较清楚的帮助我们理解这个问题:
假设当当网上用户下单买了本书,这时数据库中有条订单号为001的订单,其中有个status字段是’有效’,表示该订单是有效的;
后台管理人员查询到这条001的订单,并且看到状态是有效的
用户发现下单的时候下错了,于是撤销订单,假设运行这样一条SQL: update order_table set status = ‘取消’ where order_id = 001;
后台管理人员由于在b这步看到状态有效的,这时,虽然用户在c这步已经撤销了订单,可是管理人员并未刷新界面,看到的订单状态还是有效的,于是点击”发货”按钮,将该订单发到物流部门,同时运行类似如下SQL,将订单状态改成已发货:update order_table set status = ‘已发货’ where order_id = 001

观点1:只有冲突非常严重的系统才需要悲观锁;“所有悲观锁的做法都适合于状态被修改的概率比较高的情况,具体是否合适则需要根据实际情况判断。”,表达的也是这个意思,不过说法不够准确;的确,之所以用悲观锁就是因为两个用户更新同一条数据的概率高,也就是冲突比较严重的情况下,所以才用悲观锁。

观点2:最后提交前作一次select for update检查,然后再提交update也是一种乐观锁的做法,的确,这符合传统乐观锁的做法,就是到最后再去检查。但是wiki在解释悲观锁的做法的时候,’It is not appropriate for use in web application development.’, 现在已经很少有悲观锁的做法了,所以我自己将这种二次检查的做法也归为悲观锁的变种,因为这在所有乐观锁里面,做法和悲观锁是最接近的,都是先select for update,然后update

在实际应用中我们在更新数据的时候,更严谨的做法是带上更新前的“状态”,如

update order_table set status = ‘取消’ where order_id = 001 and status = ‘待支付’ and ..........;

update order_table set status = ‘已发货’ where order_id = 001 and status = ‘已支付’ and ..........;

然后在业务逻辑代码里判断更新的记录数,为0说明数据库已经被更新了,否则是正常的。

乐观锁和悲观锁的区别(最全面的分析)相关推荐

  1. 乐观锁和悲观锁区别以及使用场景

    乐观锁和悲观锁是并发控制中两种不同的策略,用于解决多个线程或进程同时访问和修改共享数据时可能出现的并发问题. 悲观锁 悲观锁的基本思想是,在数据被访问时,假设会有其他的线程或进程也会访问这个数据,所以 ...

  2. 面试题之——乐观锁和悲观锁区别

    对于乐观锁和悲观锁的区别及应用,要牢记一句话:读取频繁使用乐观锁,写入频繁使用悲观锁 本文转自:https://blog.csdn.net/L_BestCoder/article/details/79 ...

  3. Mysql乐观锁与悲观锁的区别

    原文地址: 05 mysql-乐观锁与悲观锁的区别 文章目录 1.悲观锁 2.乐观锁 3.两种锁的使用场景 4.乐观锁常见的两种实现方式 4.1. 版本号机制 4.2. CAS算法 5.乐观锁的缺点 ...

  4. 乐观锁和悲观锁的区别及使用场景

    转载自:https://blog.csdn.net/u010739551/article/details/81184203 悲观锁 悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每 ...

  5. java中的锁---乐观锁与悲观锁的区别

    锁,是开发中不得不掌握的一个知识点. 在面试中也会经常问到.其中乐观锁与悲观锁为最常见.首先介绍下两种锁 一:乐观锁: 1 介绍: 它的心态很好,每次别人使用它的时候,它会乐观的认为别人不修改数据,所 ...

  6. 乐观锁与悲观琐的区别

    锁.我们知道,最常用的处理多用户并发访问的方法是加锁.当一个用户锁住数据库中的某个对象时,其他用户就不能再访问该对象.加锁对并发访问的影响体现在锁的粒度上.比如,放在一个表上的锁限制对整个表的并发访问 ...

  7. 乐观锁与悲观锁的区别

    乐观锁和悲观锁都是用于解决并发场景下的数据竞争问题,但是却是两种完全不同的思想.它们的使用非常广泛,也不局限于某种编程语言或数据库. 乐观锁的概念: 乐观锁:指的是在操作数据的时候非常乐观,乐观地认为 ...

  8. [精选]MySQL的各种锁(表锁,行锁,悲观锁,乐观锁,间隙锁,死锁)

    不少人在开发的时候,应该很少会注意到这些锁的问题,也很少会给程序加锁(除了库存这些对数量准确性要求极高的情况下),即使我们不会这些锁知识,我们的程序在一般情况下还是可以跑得好好的.因为数据库隐式帮我们 ...

  9. 乐观锁和悲观锁,可重入锁和不可重入锁(1)

    乐观锁和悲观锁,可重入锁和不可重入锁(1) 前言 感觉有一段时间没有写博客了呢.还是再接再厉吧,适当程度的总结能让我自己能够更加深入地巩固和理解自己所学习的一切. 还有,我很懒,而且我还是比较喜欢写日 ...

  10. Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--悲观锁( ...

最新文章

  1. 电脑粉碎文件 c语言,文件操作(二):文件粉碎机
  2. 【Android 应用开发】BluetoothAdapter解析
  3. graphpad 折线图横坐标比例_GraphPad Prism绘制剂量反应曲线
  4. Cloudstreams: 云间整合的下一个挑战
  5. 识辨 | 什么是分类?什么是聚类?
  6. 微信小程序视频自定义进度条
  7. 【查看Python导入包的地址】
  8. springboot引入validation
  9. B站首个千万级up主!论老番茄是如何炼成的!
  10. 使用 FFmpeg 生成 ts 切片并使用 AES-128 加密
  11. 关于keras.sum()和kears.softmax()等函数中维度的理解
  12. 墙外干货:如何通过风格指南驱动模块化交互设计
  13. 小米5查看设备号信息及验证type-c数据线
  14. 数部视频学习资源,一定有你想要的
  15. 武汉坚守第六十三天——七九已满疫未退,印度大法上棍棒
  16. go加密算法:非对称加密(三)--Elliptic
  17. 解决maven打包 无法加载本地lib/下的jar包问题(程序包XXX不存在)
  18. Chrome开发者工具-阅读列表
  19. [pwn]格式化字符串:0ctf 2015 login writeup
  20. 如何将dxf或dwg等CAD文件与卫星影像地图叠加进行绘图设计?

热门文章

  1. Xcode文件被锁定:The file .xcodeproj could not be unlocked
  2. 配置Citrix Receiver 3.x、4.x支持添加HTTP站点
  3. 两步实现 mysql 远程连接
  4. Hibernate的generator属性之意义【转】
  5. springboot1.5升级2.0后遇到的问题
  6. 教你打包Java程序,jar转exe随处可跑
  7. ES6,你不得不学!
  8. RESTful Web Services初探
  9. C# 转换人民币大小金额(WinForm、Asp.Net)
  10. ashx+jQuery,一个轻量级的asp.net ajax解决方案