sql >> Databáze >  >> RDS >> Oracle

Jak mohu automaticky odemknout tabulky v Oracle po určité době?

Za prvé, uzamčení tabulky nezabrání další relaci ve vydání SELECT prohlášení proti datům.

Pokud v relaci 1 uzamknu stůl

SQL> lock table foo in exclusive mode;

Table(s) Locked.

Poté mohu spustit relaci 2 a dotazovat se na data, jak jen bych chtěl

SQL> select * from foo;

      COL1
----------
         1
         1

V Oracle zapisovače neblokují čtečky, takže nikdy nemůžete zabránit další relaci v dotazování na data v tabulce.

Zdá se, že to, co se snažíte implementovat, je pesimistické zamykání. V takovém případě místo uzamčení tabulky provedete SELECT FOR UPDATE která uzamkne konkrétní záznam, který hodláte zpracovat. Pokud se všechny ostatní relace také pokusí provést SELECT FOR UPDATE (v závislosti na verzi Oracle, případně přidání SKIP LOCKED kvalifikátor a/nebo WAIT kvalifikátor). To uzamkne konkrétní řádek, který zpracováváte, a umožní druhé relaci buď vybrat jiný řádek, nebo časový limit, nebo zjistit, že v závislosti na specifikách implementace nejsou žádné řádky ke zpracování. To nezahrnuje uzamčení stolu.

Jediným způsobem, jak může být zámek uvolněn, je, že relace, která jej získala, jej uvolní (obvykle ukončením transakce) nebo bude ukončena relace, která jej získala. Pokud je klientská aplikace stále spuštěna, ale nedělá nic pro uvolnění zámku nebo ukončení relace, bude zámek pozastaven na dobu neurčitou. DBA by musel explicitně ukončit relaci, nechat transakci vrátit zpět a uvolnit zámek, aby se systém mohl znovu pohybovat. Pokud klientská aplikace přestane běžet nebo alespoň přestane reagovat (stále mi není přesně jasné, o jakém scénáři selhání mluvíte), je možné, že povolení detekce mrtvých spojení (DCD) prostřednictvím Parametr 'SQLNET.EXPIRE_TIME' na úrovni databáze by databáze zjistila, že klient nereaguje, a automaticky ukončí relaci, vrátí transakci zpět a uvolní zámek.

Pokud však data zpracovává více relací, je obecně mnohem vhodnější použít nějakou formu optimistického zamykání. V opačném případě navrhujete systém, který bude nevyhnutelně potřebovat DBA, aby naléhavě našel a zabil relace, aby obchodní uživatelé znovu pracovali, a to bude vyžadovat stále více zásahů, čím více bude zaneprázdněn. To není něco, co by správci databází dělali rádi, a není to něco, na co si obchodní uživatelé rádi stěžují. Jednoduché optimistické zamykací schéma by bylo něco jako

  • Vyberte klíč, který chcete zpracovat, a nějaký druh data udávající, kdy byl řádek naposledy aktualizován.
  • Aktualizujte stavový sloupec na „zpracovává se“, aby se ostatní relace nepokoušely zpracovat stejný řádek.
  • Zpracujte záznam v přihlášce
  • Po dokončení zpracování aktualizujte data pomocí klíče a času, které jste vybrali v prvním kroku. Pokud aktualizujete 1 řádek, víte, že žádná jiná relace nezměnila dotyčná data, protože jste je vybrali. Pokud aktualizujete 0 řádků, víte, že nějaká jiná relace změnila data od doby, kdy jste je vybrali.

S tímto druhem architektury je poměrně snadné dotazovat se databáze, abyste viděli, jaké řádky se zpracovávají, a například mít úlohu, která po určité době nastaví stavový sloupec zpět na „nezpracováno“, pokud to klient neudělal. hotovo. Pro ostatní relace je opravdu snadné vybrat ke zpracování jiný řádek. A je to relativně bezpečné, pokud například aplikace na několik hodin zamrzne a pak se obnoví, protože po dokončení zpracování zjistí, že nějaká jiná relace již řádek znovu zpracovala.




  1. Omezení terminologie MySQL vs rozdíl cizích klíčů?

  2. MySQL v docker-compose -- přístup odepřen

  3. python manage.py migrate neprovádí žádné změny v databázi postgres

  4. uložit seznam<třída modelu> do sqlite