sql >> Database teknologi >  >> RDS >> Mysql

Sådan undgår du MySQL 'Deadlock fundet, når du forsøger at få lås; prøv at genstarte transaktion'

Et nemt trick, der kan hjælpe med de fleste dødvande, er at sortere operationerne i en bestemt rækkefølge.

Du får en deadlock, når to transaktioner forsøger at låse to låse ved modsatte ordrer, dvs.:

  • forbindelse 1:låser nøgle(1), låser nøgle(2);
  • forbindelse 2:låser nøgle(2), låser nøgle(1);

Hvis begge kører på samme tid, vil forbindelse 1 låse nøgle(1), forbindelse 2 låse nøgle(2), og hver forbindelse vil vente på, at den anden slipper nøglen -> dødlås.

Hvis du nu ændrede dine forespørgsler, så forbindelserne ville låse nøglerne i samme rækkefølge, dvs.:

  • forbindelse 1:låser nøgle(1), låser nøgle(2);
  • forbindelse 2:låser nøgle(1 ), låser nøgle(2 );

det vil være umuligt at få et dødvande.

Så dette er, hvad jeg foreslår:

  1. Sørg for, at du ikke har andre forespørgsler, der låser adgang til mere end én nøgle ad gangen, bortset fra delete-erklæringen. hvis du gør (og det formoder jeg, du gør), bestil deres WHERE i (k1,k2,..kn) i stigende rækkefølge.

  2. Ret din sletteerklæring til at fungere i stigende rækkefølge:

Skift

DELETE FROM onlineusers 
WHERE datetime <= now() - INTERVAL 900 SECOND

Til

DELETE FROM onlineusers 
WHERE id IN (
    SELECT id FROM onlineusers
    WHERE datetime <= now() - INTERVAL 900 SECOND 
    ORDER BY id
) u;

En anden ting at huske på er, at MySQL-dokumentationen tyder på, at klienten i tilfælde af dødvande skal prøve igen automatisk. du kan tilføje denne logik til din klientkode. (Sig, 3 forsøg på denne særlige fejl, før du giver op).



  1. Sådan fungerer RPAD() i MariaDB

  2. Hvordan opretter man en sikker mysql forberedt erklæring i php?

  3. Returner det aktuelle arbejdsstationsnavn, der er forbundet til SQL Server (T-SQL)

  4. Postgresql-kolonnen blev ikke fundet, men vises i beskrivelsen