MST

星途 面试题库

面试题:MySQL中死锁是如何产生的,常见的死锁场景有哪些?

请详细阐述MySQL数据库中死锁产生的原因,并列举至少两种常见的会导致死锁的场景。
43.6万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试

死锁产生原因

死锁是指两个或多个事务在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。在MySQL数据库中,死锁产生主要源于以下几点:

  1. 资源竞争:多个事务同时对相同的资源(如锁)进行竞争。例如多个事务都想获取同一行数据的锁来进行修改操作。
  2. 事务的隔离性:MySQL的事务隔离级别(如读已提交、可重复读等)会影响锁的行为和持有时间。在某些隔离级别下,锁的持有时间可能较长,增加了死锁发生的概率。
  3. 循环等待:事务之间形成了一个循环依赖关系。例如事务A持有资源R1并等待资源R2,而事务B持有资源R2并等待资源R1,从而导致死锁。

常见导致死锁的场景

  1. 并发更新同一行数据: 假设有两个事务T1和T2,都要对同一行数据进行更新操作。
    • T1首先获取该行数据的锁,开始执行更新操作,但未提交。
    • 此时T2也尝试获取该行数据的锁,由于T1未释放锁,T2处于等待状态。
    • 若T1接下来又尝试获取其他资源(例如另一行数据的锁),而该资源已被T2持有,T1也进入等待状态,这样就形成了死锁。
  2. 事务执行顺序不当: 假设有两个事务T1和T2,分别操作两张表TableA和TableB。
    • T1按顺序获取TableA的锁,然后尝试获取TableB的锁。
    • T2按相反顺序,先获取TableB的锁,再尝试获取TableA的锁。
    • 如果T1获取TableA锁后,T2获取TableB锁,之后双方都尝试获取对方已持有的锁,就会造成死锁。
  3. 锁升级: 在某些情况下,MySQL会将细粒度的锁升级为粗粒度的锁。例如,一个事务对某行数据加了行级锁,随着事务的执行,当需要锁定更多行时,MySQL可能会将行级锁升级为表级锁。如果多个事务都发生锁升级,就可能导致死锁。比如事务T1对表中部分行加了行锁,事务T2对另外部分行加了行锁,当T1和T2都进行锁升级时,可能会相互等待对方释放锁,进而产生死锁。