sql server 悲观锁和乐观锁的作用
2024-08-27 10:59:25
sql server对并发的处理-乐观锁和悲观锁
假如两个线程同时修改数据库同一条记录,就会导致后一条记录覆盖前一条,从而引发一些问题。
例如:
一个售票系统有一个余票数,客户端每调用一次出票方法,余票数就减一。
情景:
总共300张票,假设两个售票点,恰好在同一时间出票,它们做的操作都是先查询余票数,然后减一。
一般的sql语句:
declare @ count as int begin tran select @ count = count from ttt WAITFOR DELAY '00:00:05' --模拟并发,故意延迟5秒 update ttt set count =@ count -1 commit TRAN SELECT * FROM ttt |
问题就在于,同一时间获取的余票都为300,每个售票点都做了一次更新为299的操作,导致余票少了1,而实际出了两张票。
打开两个查询窗口,分别快速运行以上代码即可看到效果。
定义解释:
悲观锁:相信并发是绝大部分的,并且每一个线程都必须要达到目的的。
乐观锁:相信并发是极少数的,假设运气不好遇到了,就放弃并返回信息告诉它再次尝试。因为它是极少数发生的。
悲观锁解决方案:
declare @ count as int begin tran select @ count = count from tb WITH (UPDLOCK) WAITFOR DELAY '00:00:05' --模拟并发,故意延迟5秒 update tb set count =@ count -1 commit tran |
在查询的时候加了一个更新锁,保证自查询起直到事务结束不会被其他事务读取修改,避免产生脏数据。
从而可以解决上述问题。
乐观锁解决方案:
--首先给表加一列timestamp ALTER TABLE ttt ADD timesFlag TIMESTAMP NOT null 然后更新时判断这个值是否被修改 declare @ count as int DECLARE @flag AS TIMESTAMP DECLARE @rowCount AS int begin tran select @ count = COUNT ,@flag=timesflag from ttt WAITFOR DELAY '00:00:05' update ttt set count =@ count -1 WHERE timesflag=@flag --这里加了条件 SET @rowcount=@@ROWCOUNT --获取被修改的行数 commit TRAN --对行数进行判断即可 IF @rowCount=1 PRINT '更新成功' ELSE PRINT '更新失败' |
这便是乐观锁的解决方案,可以解决并发带来的数据错误问题,但不保证每一次调用更新都成功,可能会返回'更新失败'
悲观锁和乐观锁
悲观锁一定成功,但在并发量特别大的时候会造成很长堵塞甚至超时,仅适合小并发的情况。
乐观锁不一定每次都修改成功,但能充分利用系统的并发处理机制,在大并发量的时候效率要高很多。
最新文章
- JS 判断字串字节数,并截取长度
- C++如何调用C#开发的dll
- 3.bootstrap练习笔记-媒体内容
- linux系统一键安装phpstudy的lnmp环境
- discuz手机版模板开发
- 详解c++指针的指针和指针的引用(转)
- php部分--session的三种用法
- linux 的终端字体色和背景色的修改方法(二)
- 前端编码风格规范(3)—— JavaScript 规范
- KVC/KVO总结
- 解决Cacti监控图像断断续续问题
- Android ListView嵌套Button,Button事件覆盖item事件解决办法
- L10 数据入站、转发、出站流程
- 快速排序算法C#实现
- DOM知识梳理
- maven 阿里云仓库配置
- 如何解决JavaScript中0.1+0.2不等于0.3
- c# 深入探索之CLR
- 2019,UI设计师必备神器
- LINUX中关于SIGNAL的定义
热门文章
- Visual Studio Code 中实现 C++ 函数定义跳转和代码自动补全功能(25)
- django初识1
- django使用pyecharts(2)----django加入echarts_前后台分离
- Python--列表中字符串按照某种规则排序的方法
- C++进行字母大小写转换
- TZOJ5703: C++实验:学生成绩类的实现
- 在论坛中出现的比较难的sql问题:35(时间间隔计算问题)
- ajax实现文件上传,多文件上传,追加参数
- 如何判断当前修改过的datatable的某一列值是否为int型或double类型
- windows下搭建nginx负载均衡