sql >> Databáze >  >> RDS >> Mysql

Jak se vyhnout MySQL 'Deadlock nalezený při pokusu o získání zámku; zkuste restartovat transakci'

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:

  1. 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í.

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



  1. Příklady MySQL REGEXP

  2. ORA-01034:ORACLE není k dispozici ORA-27101:sféra sdílené paměti neexistuje

  3. Jak efektivně používat MySQLDB SScursor?

  4. Jak databáze podporují podniky elektronického obchodu