阅读 26

Mysql——锁

行锁

在MyISAM引擎中,并没有行锁,需要并发控制的时候,只能够使用表级别锁;InnoDB引擎是存在行锁的。

两阶段提交协议

在InnoDB引擎中行锁是执行语句使用的时候回加上,事务提交的时候才会释放,即:执行完对应的语句并不会立即释放行锁。我们把这种行锁的使用协议,称作为两阶段提交

image.png

如上图,每一行对应时间线。 事务A开始执行update语句的时候会持有id为1和2的行锁,这个时候执行事务B的update语句时,事务B想要申请id为1的行锁,但是该锁被事务A获取了,所以事务B处于等待阶段。等到事务A提交之后,id为1和2的行锁才会释放,此时事务B才能够尝试去获取id为1的行锁。

由上例子可得,我们在写代码的时候,如果一个事务中会持有多个行锁,我们需要将最有可能产生冲突的行放置在最末尾,这样持有行锁的时间能够控制在最短。

死锁以及死锁检测

当事务A持有1行锁,并需要申请2行锁,且事务B持有2行锁,并需要申请1行锁。这种情况下,事务A与事务B都处于无限等待中,这种情况称之为死锁。详情如下图。

image.png

这时候,mysql有两种处理策略:

  • 进入等待,直到等待时间超过innodb_local_wait_timeout(默认值50s),事务才会释放行锁;
  • 发动死锁检测,检测到发生死锁的时候,将其中一个事务回滚,让其他事务能够正常进行。

什么是死锁检测呢?
当一个事务A被锁住的时候,会检查事务A中持有的锁有没有把其他事务B锁住,如果事务B申请的锁恰好被事务A持有,则事务A、B处于死锁。

引用

极客时间——MySQL实战45讲《第七讲》——丁奇

文章分类
后端
文章标签