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:
-
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.
-
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).