sql >> Databasteknik >  >> RDS >> Mysql

Hur man undviker MySQL 'Deadlock hittas när man försöker få lås; försök starta om transaktionen'

Ett enkelt knep som kan hjälpa till med de flesta dödlägen är att sortera operationerna i en specifik ordning.

Du får ett dödläge när två transaktioner försöker låsa två lås vid motsatta order, dvs:

  • anslutning 1:låser nyckel(1), låser nyckel(2);
  • anslutning 2:låser nyckel(2), låser nyckel(1);

Om båda körs samtidigt, låser anslutning 1 nyckel(1), anslutning 2 låser nyckel(2) och varje anslutning väntar på att den andra släpper nyckeln -> blockerat låsläge.

Nu, om du ändrade dina frågor så att anslutningarna skulle låsa nycklarna i samma ordning, dvs:

  • anslutning 1:låser nyckel(1), låser nyckel(2);
  • anslutning 2:låser nyckel (1 ), låser nyckel (2 );

det kommer att vara omöjligt att få ett dödläge.

Så det här är vad jag föreslår:

  1. Se till att du inte har några andra frågor som låser åtkomst till mer än en nyckel åt gången förutom delete-satsen. om du gör det (och jag misstänker att du gör det), beställ deras WHERE i (k1,k2,..kn) i stigande ordning.

  2. Åtgärda din raderingssats så att den fungerar i stigande ordning:

Ändra

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

Till

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

En annan sak att tänka på är att MySQL-dokumentationen tyder på att klienten ska försöka igen automatiskt i händelse av ett dödläge. du kan lägga till denna logik i din klientkod. (Säg, 3 försök igen på detta specifika fel innan du ger upp).



  1. Hur får man tabelldefinition i Oracle?

  2. Hur infogar man en tidsstämpel i Oracle?

  3. Hur väljer jag alla kolumner från en tabell, plus ytterligare kolumner som ROWNUM?

  4. Refererar du till Oracle användardefinierade typer över DBLINK?