Een eenvoudige truc die bij de meeste impasses kan helpen, is de bewerkingen in een specifieke volgorde te sorteren.
U krijgt een impasse wanneer twee transacties proberen om twee vergrendelingen in tegengestelde volgorde te vergrendelen, dat wil zeggen:
- verbinding 1:vergrendelt sleutel(1), vergrendelt sleutel(2);
- verbinding 2:vergrendelt sleutel(2), vergrendelt sleutel(1);
Als beide tegelijkertijd werken, vergrendelt verbinding 1 de sleutel (1), vergrendelt verbinding 2 de sleutel (2) en wacht elke verbinding tot de andere de sleutel loslaat -> deadlock.
Als u nu uw zoekopdrachten zodanig heeft gewijzigd dat de verbindingen de toetsen in dezelfde volgorde zouden vergrendelen, dat wil zeggen:
- verbinding 1:vergrendelt sleutel(1), vergrendelt sleutel(2);
- verbinding 2:vergrendelt sleutel(1 ), vergrendelt sleutel(2 );
het zal onmogelijk zijn om een impasse te krijgen.
Dus dit is wat ik voorstel:
-
Zorg ervoor dat u geen andere query's hebt die de toegang tot meer dan één sleutel tegelijk blokkeren, behalve de delete-instructie. als je dat doet (en ik vermoed dat je dat doet), bestel dan hun WHERE in (k1,k2,..kn) in oplopende volgorde.
-
Pas uw verwijderopdracht aan zodat deze in oplopende volgorde werkt:
Wijzigen
DELETE FROM onlineusers
WHERE datetime <= now() - INTERVAL 900 SECOND
Naar
DELETE FROM onlineusers
WHERE id IN (
SELECT id FROM onlineusers
WHERE datetime <= now() - INTERVAL 900 SECOND
ORDER BY id
) u;
Een ander ding om in gedachten te houden is dat MySQL-documentatie suggereert dat in het geval van een impasse de client het automatisch opnieuw moet proberen. u kunt deze logica toevoegen aan uw klantcode. (Zeg, 3 pogingen op deze specifieke fout voordat je opgeeft).