当前位置: 首页 > news >正文

程序员角度的锁--乐观锁、悲观锁

参考链接:

http://www.digpage.com/lock.html

http://blog.csdn.net/hongchangfirst/article/details/26004335

 

乐观锁 (Optimistic Lock)

顾名思义,就是很乐观,假设数据一般情况下不会造成冲突,只有在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。一般使用数据版本、timespan来实现。

何谓数据版本?即为数据增加一个版本号。在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,并加1,提交更新时,先将待提交数据的版本号与数据库表中对应记录的版本号进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

如:数据库的版本号是0,   读取0,然后加1,得到1.

提交的时候, 和数据库对比,  此时如果数据库中仍然是0, 则1>0,  可以更新,  如果库中版本号大于0,  则不允许更新。

 

乐观锁失效

乐观锁存在失效的情况,属小概率事件,需要多个条件共同配合才会出现。如:

  • 应用采用自己的策略管理主键ID。如,常见的取当前ID字段的最大值+1作为新ID。
  • 版本号字段 ver 默认值为 0 。
  • 用户A读取了某个记录准备修改它。该记录正好是ID最大的记录,且之前没被修改过, ver 为默认值 0。
  • 在用户A读取完成后,用户B恰好删除了该记录。之后,用户C又插入了一个新记录。
  • 此时,阴差阳错的,新插入的记录的ID与用户A读取的记录的ID是一致的, 而版本号两者又都是默认值 0。
  • 用户A在用户C操作完成后,修改完成记录并保存。由于ID、ver均可以匹配上, 因此用户A成功保存。但是,却把用户C插入的记录覆盖掉了。

乐观锁此时的失效,根本原因在于应用所使用的主键ID管理策略, 正好与乐观锁存在极小程度上的不兼容。

 

悲观锁

悲观锁,正如其名,它指的是对数据被其他事务修改持悲观态度,因此,在事务A处理数据的过程中,一直将数据锁定,这样其他想拿这个数据就会block住,直到事务A放开锁。

悲观锁的实现,往往依靠数据库提供的锁机制 (也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)

 

转载于:https://www.cnblogs.com/yfdream/p/7843140.html

相关文章:

  • msf生成php,MSF-Shellcode生成和使用
  • 如何在首次启动 Linux 虚拟机时对其进行自定义
  • php 比nodejs 容易学,粗大事了:花两天时间学习了 Go 语言,发现比 Node.js 高不知多少去了...
  • php获取cname解析结果,如何检测来自CNAME子域的传入请求(使用PHP脚本)?
  • Ubuntu16.04系统中Nmon的安装
  • CentOS 7 网络磁盘挂载到本地 并测试传输速度
  • 数字图像处理灰度变换java,数字图像处理:图像的灰度变换(Matlab实现)
  • java math 最大,在Java.lang包的Math类中,求最大值的方法为(选一项)
  • 递推算法
  • java方法传递对象,java面向对象-3-方法参数传递
  • iOS 对UIAlertController内的输入框进行输入监听,实时改变确定、取消按钮颜色
  • php url别名,编写PHP程序实现Drupal中pathauto模块的批量生成URL别名(Alias)
  • Spark记录-spark与storm比对与选型(转载)
  • matlab 实验七,matlab 实验七 数字填图问题
  • matlab corrcoef 原理,cov函数 corrcoef函数【Matlab】
  • CentOS从零开始部署Nodejs项目
  • Consul Config 使用Git做版本控制的实现
  • C学习-枚举(九)
  • Go 语言编译器的 //go: 详解
  • HTML5新特性总结
  • IDEA 插件开发入门教程
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Linux下的乱码问题
  • Ruby 2.x 源代码分析:扩展 概述
  • Yii源码解读-服务定位器(Service Locator)
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 前端工程化(Gulp、Webpack)-webpack
  • 前嗅ForeSpider中数据浏览界面介绍
  • 软件开发学习的5大技巧,你知道吗?
  • 少走弯路,给Java 1~5 年程序员的建议
  • 试着探索高并发下的系统架构面貌
  • 说说动画卡顿的解决方案
  • 算法系列——算法入门之递归分而治之思想的实现
  • 通过npm或yarn自动生成vue组件
  • 译米田引理
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 原生 js 实现移动端 Touch 滑动反弹
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • # centos7下FFmpeg环境部署记录
  • #pragma data_seg 共享数据区(转)
  • #QT(TCP网络编程-服务端)
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (1)SpringCloud 整合Python
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (52)只出现一次的数字III
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (zhuan) 一些RL的文献(及笔记)
  • (超详细)语音信号处理之特征提取
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (转)fock函数详解
  • ******IT公司面试题汇总+优秀技术博客汇总