✦ Oplossingen · Database (MySQL/MariaDB)

MySQL: Deadlock found when trying to get lock

'ERROR 1213: Deadlock found when trying to get lock; try restarting transaction' ontstaat als twee transacties op elkaar wachten. Zo lees je de deadlock en voorkom je herhaling.

Waarom gebeurt dit?

Een deadlock ontstaat als transactie A een rij vasthoudt die B nodig heeft, terwijl B een rij vasthoudt die A nodig heeft. Geen van beide kan verder. InnoDB herkent dat direct, kiest één transactie als 'slachtoffer', draait die terug en geeft fout 1213.

Een enkele deadlock bij drukte is normaal en hoort de applicatie op te vangen door de transactie opnieuw te proberen. Komen ze vaak voor, dan worden rijen in verschillende volgorde vergrendeld of ontbreken er indexen.

Zo los je het op, stap voor stap

Menunamen kunnen per versie of toestel iets anders heten. Loop de stappen op volgorde af en stop zodra het werkt.

  1. Lees de laatste deadlock

    InnoDB bewaart de laatste deadlock in de statusuitvoer, onder LATEST DETECTED DEADLOCK, met beide queries.

    SHOW ENGINE INNODB STATUS\G
  2. Log alle deadlocks

    Zet tijdelijk logging aan om te zien hoe vaak het gebeurt en welke queries betrokken zijn.

    SET GLOBAL innodb_print_all_deadlocks = ON;
  3. Vergrendel in een vaste volgorde

    Laat alle code die meerdere rijen of tabellen wijzigt dat in dezelfde volgorde doen, bijvoorbeeld altijd op oplopend id. Dan kan de kringloop niet ontstaan.

  4. Houd transacties kort en geïndexeerd

    Hoe korter een transactie en hoe minder rijen hij vergrendelt, hoe kleiner de kans. Indexen op de kolommen in WHERE helpen daarbij.

  5. Probeer opnieuw in de code

    Vang fout 1213 af en voer de transactie een paar keer opnieuw uit.

    <?php
    for ($poging = 1; $poging <= 3; $poging++) {
        try {
            $pdo->beginTransaction();
            // ... wijzigingen ...
            $pdo->commit();
            break;
        } catch (PDOException $e) {
            $pdo->rollBack();
            if (($e->errorInfo[1] ?? 0) !== 1213 || $poging === 3) {
                throw $e;
            }
        }
    }

Lukt het niet? Wij helpen

Kom je er met deze stappen niet uit, of wil je het liever niet zelf doen? We kijken online mee of komen langs. Hulp op afstand kost €20 per uur; komen we langs, dan is de prijs op aanvraag. Je weet vooraf waar je aan toe bent.

Aanvraag

Hulp aanvragen

Schrijf kort wat er misgaat en wat je al hebt geprobeerd. Kies of we bellen, online meekijken of langskomen.

Veelgestelde vragen

Vragen over dit probleem

Is een deadlock een bug in MySQL?

Nee. Het is een gevolg van hoe twee transacties tegelijk werken. De database lost het op door er één af te breken.

Gaat er data verloren?

De afgebroken transactie wordt volledig teruggedraaid. Er gaat niets half mis, maar de wijziging moet opnieuw worden uitgevoerd.

Helpt een andere isolatieniveau?

Soms vermindert READ COMMITTED het aantal locks, maar het verandert ook gedrag. Begin met volgorde, indexen en korte transacties.