mysql的锁机制(行锁表锁+悲观锁乐观锁)+死锁的产生与避免(以Innodb引擎为例)

一、mysql的锁机制

(1)悲观锁乐观锁(面试必备

行锁(悲观锁和乐观锁)解决,建议使用乐观锁,乐观锁更适合解决冲突概率极小的情况,而悲观锁则适合解决并发竞争激烈的情况

(2)行锁表锁

InnoDB实现了两种类型的行锁:

共享锁(S):允许一个事务去读一行,阻止其他事务获得相同的数据集的排他锁。(我读的时候,你可以读,但是不能写。)

排他锁(X):允许获得排他锁的事务更新数据,但是组织其他事务获得相同数据集的共享锁和排他锁。(我写的时候,你不能读也不能写。)

InnoDB还有两个表锁

意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁。(要想加S锁,必须先加IS锁)

意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。(要想加X锁,必须先加IX锁)

意向锁是InnoDB自动加的,不需要用户干预。

问:IS为何在S前加,IX为何在X前加?

答:意向锁的出现是为了更好细化锁的层级粒度,并且能提高锁处理性能:在数据库处理事务A请求的行级锁之前,会先申请该资源对应根目录资源的意向锁,以便能在其他事务B中再次请求表锁时做到阻塞。锁合理使用是:表锁、行锁同时使用

对于insert、update、deleteInnoDB会自动给涉及的数据加排他锁(X);对于一般的Select语句,InnoDB不会加任何锁

事务可以通过以下语句给显示加共享锁或排他锁:

共享锁:select * from table_name where .....lock in share mode

排他锁:select * from table_name where .....for update

 

利用select ....lock in share mode加入共享锁

利用select ....for update加入排他锁

 

 

 

 

锁的具体实现方式见:https://www.2cto.com/database/201508/429967.html中间部分

 

二、死锁的产生与避免

死锁:

我们说过MyISAM中是不会产生死锁的,因为MyISAM总是一次性获得所需的全部锁,要么全部满足,要么全部等待。

而在InnoDB中,锁是逐步获得的,就造成了死锁的可能。在上面的例子中我们可以看到,当两个事务都需要获得对方持有的锁才能够继续完成事务,导致双方都在等待,产生死锁。发生死锁后,InnoDB一般都可以检测到,并使一个事务释放锁回退,另一个获取锁完成事务。

 

避免死锁:

有多种方法可以避免死锁,这里只介绍常见的三种:

1、如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。

2、在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;

3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁粒度,通过表级锁定来减少死锁产生的概率;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值