深入理解MySQL事务隔离级别与锁机制

表锁:
行锁:

InnoDB和MyISAM最大的不同有两点:

  • InnoDB支持事务(TRANSACTION)
  • InnoDB支持行锁

MyISAM在执行查询SELECT前,会自动给涉及的所有表加读锁,在执行update、insert、delete操作会自动给涉及的表加写锁。
InnoDB在执行查询语句SELECT时(非串行隔离级别),不会加锁。但是update、insert、delete操作会加行锁。
读锁只会堵塞写,不会堵塞读,但是写锁会堵塞读和写

在这里插入图片描述
幻读例子:
客户端A查询后,客户段B插入一条数据Q,客户段A想插入Q却报主键冲突,但是查询不出来数据Q;但是可以对Q进行更新。

串行化

把所有读到的数据加锁。
效率很低,很少用。

间隙锁

间隙锁,锁的是两个值之间的间隙

一个值落到一个范围,这个范围的所有数据都会被加锁
在这里插入图片描述
如图:间隙就有id为(3,10)、(10,20)、(20,正无穷)
update account set name = ‘zhuge’ where id >8 and id <18
则其他事务没法在这个范围所包含的所有行记录(包括间隙记录)以及行记录所在的间隙里插入或修改任何数据。即id在(3,20]区间都无法修改数据,20也包含在内。

间隙锁是在可重复度隔离级别下才会生效

临键锁(Next-key-Locks)

临键锁是行锁和间隙锁的组合,想上面的例子中(3,20]的整个区间可以叫临键锁。

无索引行会升级为表锁

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级到表锁
锁主要是加在索引上,如果对非索引字段更新,行锁可能会变成表锁。

session1执行:update account set balance = 800 where name = ‘lilei’;
session2对该表任一行操作都会阻塞住。

优化建议

  • 尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁;
  • 合理设计表索引,尽量缩小锁的范围
  • 尽可能减少检索条件范围,避免间隙锁
  • 尽量控制事务大小,减少锁定资源量和时间长度,涉及事务加锁的SQL尽量放在事务最后执行;
  • 尽可能低级别事务隔离

https://note.youdao.com/ynoteshare/index.html?id=354ae85f3519bac0581919a458278a59&type=note&_time=1701862479906

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值