记录Mysql 关于 select for update 相关学习

 

应用场景:

高并发条件下频繁更改数据库导致数据出错

eg: A 和B 同时发起订单 总库存为1 A已经 库存-1 同时间B也进行库存-1操作导致问题发生

所以使用for update 加锁保证数据正常

原则: 一锁二判三更新

for update 仅仅用于InnoDB 引擎 且在事务块 begin/commit 中才能生效,

在进行事务操作时,通过 “for update ” 语句对查询结果集 中的每行数据都添加排他锁,其他线程对改记录的更新与删除操作时 都会被阻塞,

排他锁包括 表锁/行锁

排他锁属于乐观锁的一种 由innodb所控制等同于 java synchronized(没确定) X

 

排他锁为悲观锁

会存在锁表和锁行的情况

表锁和行锁触发场景

1.查询到数据

2.查询主键 / 索引字段 查询到数据

重点

 

 

上述文字所说:

当带有主键进行查询,得到数据 其他线程再次携带主键进行查询 则 主键字段产生行锁;

如果其他线程不带主键/不含索引字段进行查询 则非主键不含索引字段产生表锁

如果其他相乘不带主键/带索引字段进行查询 则非主键含索引字段产生行锁(如果该索引字段为ENM枚举类型,则也会进行表锁)

自己总结:

带索引则产生行锁 ,不带索引则带表锁, 其次索引字段为枚举类型也会产生表锁

 原文总结:

1、InnoDB行锁是通过给索引上的索引项加锁来实现的,只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。

2、由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。

3、当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。

4、即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真正使用了索引。

5、检索值的数据类型与索引字段不同,虽然MySQL能够进行数据类型转换,但却不会使用索引,从而导致InnoDB使用表锁。通过用explain检查两条SQL的执行计划,我们可以清楚地看到了这一点。

 

原文档链接 感谢大佬

https://zhuanlan.zhihu.com/p/143866444

posted @   25岁我想赚钱  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示