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

MySql FOR UPDATE 锁的一点问题……

问题描述

假设一个情况,这里只是假设,真实的情况可能不会这样设计,但是假如真的发生了....
铁老大有一张这样的ticket表,用来存放北京到上海的票。

id
uid
start_addr
end_addr
book_time
1
1300009860
上海
北京
13866660321
2
0
上海
北京
3
0
上海
北京
4
0
上海
北京

uid 不等于0 并且 book_time 不等于0,则表示已售出,不许再更改。
年底了,大家开始抢了,当某一个人开始抢的时候,铁老大这样做了,当A开始抢的时候,从表中所有uid=0的记录中随机取出一条,然后修改当前记录的uid为A的uid,book_time为当前时间。
那么好了,这个时候并发产生了,10000个人同时抢最后剩下的10张票,有2个人A,B同时读取了uid=0 and id=2的记录,然后A把uid修改为自己的,book_time修改timeA,系统通知A抢票成功 紧接着,B同样修改了这条记录为自己的,那么这个时候A的票就失效了。
这里就考虑使用锁机制了,如果在A读取了这条记录后,并把这条记录加上写锁,那么别人就无法再读取加锁,也就不会修改多次了。

实验结果

实验了一下for update 加锁,然后发现了一些问题。
1、当我们使用主键查询去加锁的时候,可以对这条记录加行锁
打开一个终端:执行一下代码:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from ticket where id = 2 for update;

那么 id=2这个记录就会被加行写锁。
令一个终端将无法读取该记录,但是却可以读取其他记录

#可以读取加锁
mysql> select * from ticket where id = 3 for update;
#不可以读取
mysql> select * from ticket where id = 2 for update;

2、但是当我们按非主键查询会怎样呢

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from ticket where uid = 0 limit 1 for update;

那么这个时候,这个表会被锁住,任何记录都不能再读取加锁

//不可读取,等待释放锁
mysql> select * from ticket where id = 1 for update;
//不可读取等待释放锁
mysql> select * from ticket where uid = 0 limit 1 for update;

但是表锁会减少并发。

结论

有没有一种方法,可以在非主键字段查询一条记录时上实现加行写锁,期待高手支招。




相关文章:

  • FineUploader 学习笔记
  • 大一下学期,大二上学期,这一年
  • mysql 关于自增字段的一些说明
  • Hyper-v学习(三),虚拟机实时迁移之存储迁移
  • Jquery - 属性选择器
  • typeof instanceof
  • HashMap vs. TreeMap vs. Hashtable vs.LinkedHashMap
  • 第二十二课:磁滞和麦克斯韦方程组
  • JOOMLA中文安装时 数据库发生错误解块办法
  • haproxy介绍
  • 毕设问题小记——Spring事务配置
  • 对象.delegate=self的理解
  • vsftp虚拟用户配置
  • DevExpress控件使用系列--ASPxUploadControl(图片上传及预览)
  • linux 常用操作命令
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 【笔记】你不知道的JS读书笔记——Promise
  • Druid 在有赞的实践
  • If…else
  • mysql常用命令汇总
  • ng6--错误信息小结(持续更新)
  • python3 使用 asyncio 代替线程
  • Python3爬取英雄联盟英雄皮肤大图
  • vue2.0项目引入element-ui
  • 关于Java中分层中遇到的一些问题
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 那些被忽略的 JavaScript 数组方法细节
  • 使用 @font-face
  • 译自由幺半群
  • 用Canvas画一棵二叉树
  • AI算硅基生命吗,为什么?
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​MySQL主从复制一致性检测
  • ​TypeScript都不会用,也敢说会前端?
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • (六)Hibernate的二级缓存
  • (三分钟)速览传统边缘检测算子
  • (转载)CentOS查看系统信息|CentOS查看命令
  • (转载)hibernate缓存
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .net 4.0发布后不能正常显示图片问题
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET 药厂业务系统 CPU爆高分析
  • .net连接oracle数据库
  • @transactional 方法执行完再commit_当@Transactional遇到@CacheEvict,你的代码是不是有bug!...
  • [ 英语 ] 马斯克抱水槽“入主”推特总部中那句 Let that sink in 到底是什么梗?
  • [20180224]expdp query 写法问题.txt
  • [BT]小迪安全2023学习笔记(第15天:PHP开发-登录验证)
  • [CDOJ 1343] 卿学姐失恋了
  • [CISCN2019 华北赛区 Day1 Web2]ikun
  • [codevs] 1029 遍历问题
  • [CQOI 2010]扑克牌