454-MySQL(意向共享锁,意向排他锁和死锁)

InnoDB表级锁

我们在之前知道,InnoDB是行锁,但是不是每次都获取行锁,如果没有索引项的话,还是一个表锁。而且有的时候,我们希望直接去使用表锁。

在绝大部分情况下都应该使用行锁,因为事务和行锁往往是选择InnoDB存储引擎的理由,但个别情况下也使用表级锁;
(1)事务需要更新大部分或全部数据,表又比较大,如果使用默认的行锁,给大部分行都加锁,还不如直接给整张表加锁呢。不仅这个事务执行效率低,而且可能造成其他事务长时间等待和锁冲突;
(2)事务涉及多个表,比较复杂,如果都用行锁,很可能引起死锁,造成大量事务回滚。
如:
LOCK TABLE user READ;读锁锁表(获取这张表的读锁)
LOCK TABLE user WRITE; 写锁锁表(获取这张表的写锁)
事务执行…
COMMIT/ROLLBACK; 事务提交或者回滚
UNLOCK TABLES; 本身自带提交事务,释放线程占用的所有表锁

在使用表锁的时候,涉及到效率的问题:
如果我们要获取一张表的共享锁S或者排它锁X,最起码得确定,这张表没有被其他事务获取过X锁,这张表里的数据没有被其他事务获取过行锁X锁。
在这里插入图片描述

假如这张表有1000万个数据,怎么判断这1000万行哪些有X锁哪些没有X锁???
不扫描 不知道。
得全部扫描过去才知道。

意向共享锁和意向排他锁

目的是解决效率问题:
在这里插入图片描述

都是和表锁的概念相关的。为了可以更快速的获取表锁。

意向共享锁(IS锁):事务计划给记录加行共享锁,事务在给一行记录加共享锁前,必须先取得该表的IS 锁。
意向排他锁(IX锁):事务计划给记录加行排他锁,事务在给一行记录加排他锁前,必须先取得该表的IX 锁。
在这里插入图片描述
1、意向锁是由InnoDB存储引擎获取行锁之前自己获取的
2、意向锁之间都是兼容的,不会产生冲突
3、意向锁存在的意义是为了更高效的获取表锁(表格中的X和S指的是表锁,不是行锁!!!)
4、意向锁是表级锁,协调表锁和行锁的共存关系。主要目的是显示事务正在锁定某行或者试图锁定某行。

在这里插入图片描述
在这里插入图片描述

死锁

MyISAM 表锁是 deadlock free 的, 这是因为 MyISAM 总是一次获得所需的全部锁,要么全部满足,要么等待,因此不会出现死锁。如果是处理多张表,还是可能出现死锁问题的。
在这里插入图片描述

但在 InnoDB 中,除单个 SQL 组成的事务外,锁是逐步获得的,即锁的粒度比较小,这就决定了在 InnoDB 中发生死锁是可能的。
在这里插入图片描述
死锁问题一般都是我们自己的应用造成的,和多线程编程的死锁情况相似,大部分都是由于我们多个线程在获取多个锁资源的时候,获取的顺序不同而导致的死锁问题。因此我们应用在对数据库的多个表做更新的时候,不同的代码段,应对这些表按相同的顺序进行更新操作,以防止锁冲突导致死锁问题。

死锁出现的典型场景:

事务1成功获取行锁1
事务2成功获取行锁2

然后事务1现在要获取行锁2,就要等待了。
而事务2现在要获取行锁1,也要等待了。

在这里插入图片描述
当前进行的2个事务都阻塞住了。
所有的事务都阻塞住了,相当于进程内的所有线程都阻塞住了,造成了死锁问题。

多个事务/线程 在获取多个相同资源锁的时候应该按照同样的顺序获取资源的锁
事务被阻塞了,或者死锁了,事务是不会一直阻塞在那里的,mysqld(MySQL服务器进程)是有事务阻塞的超时时间,超时后,事务处理失败。

举个例子

在这里插入图片描述

在这里插入图片描述
事务1 select
事务2 select

在这里插入图片描述
然后互相进行select对方之前select的内容
在这里插入图片描述
事务被阻塞,会有超时时间,如果是死锁,mysqld直接能自动够检测到死锁问题的发生并进行事务的回滚。

锁的优化建议

1.尽量使用较低的隔离级别(已提交读,可重复读)

2.设计合理的索引并尽量使用索引访问数据,使加锁更加准确,减少锁冲突的机会,提高并发能力

3.选择合理的事务大小,小事务发生锁冲突的概率小

4.不同的程序访问一组表时,应尽量约定以相同的顺序访问各表,对一个表而言,尽可能以固定的顺序存取表中的行。这样可以大大减少死锁的机会

5.尽量用相等条件访问数据,这样可以避免间隙锁对并发插入的影响

6.不要申请超过实际需要的锁级别

7.除非必须,查询时不要显示加锁
非必要时我们不要手动获取锁,因为有MVCC就不错了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值