Jeden snadný trik, který může pomoci s většinou uváznutí, je řazení operací v určitém pořadí.
Dostanete se do zablokování, když se dvě transakce pokoušejí uzamknout dva zámky v opačném pořadí, tj.:
- spojení 1:zamkne klíč(1), zamkne klíč(2);
- spojení 2:zamkne klíč(2), zamkne klíč(1);
Pokud obě běží současně, spojení 1 uzamkne klíč (1), připojení 2 uzamkne klíč (2) a každé připojení bude čekat, až to druhé uvolní klíč -> deadlock.
Nyní, pokud jste změnili své dotazy tak, aby připojení uzamkla klíče ve stejném pořadí, tj.:
- spojení 1:zamkne klíč(1), zamkne klíč(2);
- připojení 2:zamkne klíč (1 ), uzamkne klíč (2 );
nebude možné uváznout na mrtvém bodě.
Takže navrhuji toto:
-
Ujistěte se, že nemáte žádné další dotazy, které blokují přístup k více než jednomu klíči najednou, kromě příkazu delete. pokud ano (a mám podezření, že ano), objednejte jejich WHERE v (k1,k2,..kn) ve vzestupném pořadí.
-
Opravte svůj příkaz delete, aby fungoval ve vzestupném pořadí:
Změnit
DELETE FROM onlineusers
WHERE datetime <= now() - INTERVAL 900 SECOND
Komu
DELETE FROM onlineusers
WHERE id IN (
SELECT id FROM onlineusers
WHERE datetime <= now() - INTERVAL 900 SECOND
ORDER BY id
) u;
Další věc, kterou je třeba mít na paměti, je, že dokumentace MySQL naznačuje, že v případě zablokování by se měl klient automaticky znovu pokusit. tuto logiku můžete přidat do svého klientského kódu. (Řekněme 3 pokusy o tuto konkrétní chybu, než to vzdáte).