Pokud se aplikace připojuje na Oracle v rámci lokálního počítače, vše funguje tak, jak má. Pokud ale přistupuje přes síť, používá zámky a někdo přetrhne spojení (vypne klientský počítač „natvrdo“, vytáhne síťový kabel), Oracle si nevšimne, že se spojení rozpadlo – a zámky zůstanou zamčené, dokud s tím DBA něco neudělá. Co s tím?
Existují dvě možnosti, jak to vyřešit.
Na „soft“ úrovni je to možné pomocí „resource profilů“ – konkrétně nastavením „IDLE_TIME“.
1) Nejprve povolíme profily v dané instanci Oracle:
alter system set resource_limit=true;
2) Pak uděláme profil s limitací IDLE_TIME na 3 minuty:
CREATE PROFILE LIMPROFILE LIMIT IDLE_TIME 3;
3) A nakonec tento profil přiřadíme k uživateli:
alter user appuser profile LIMPROFILE;
Co to udělá? Pokud v rámci spojení po zadanou dobu nepřijde žádný příkaz, spojení je přerušeno. Do „idle“ time se nepočítá čas, kdy databáze něco dělá – tj. pokud mi SELECT poběží 10 minut, je to v pořádku.
Tj. nekontrolujeme rozpad spojení, ale to, že se na něm nic neděje= budeme muset do aplikace dodělat nějaké „void“ akce typu SELECT * FROM DUAL, aby spojení nikdy nebylo neaktivní déle než zadaný čas.
Pozor! Spojení ukončené pro IDLE TIME se sice uzavře, transakce rollbacknou a zámky odemknou, ale spojení zůstane v tabulce SESSIONS ve stavu „SNIPED“. DBA jej musí smazat ručně (!!!).
Druhé řešení je lepší. V souboru network/admin/SQLNET.ORA na serveru je třeba založit novou konfigurační hodnotu:
SQLNET.EXPIRE_TIME=3
Tato hodnota říká, že pokud v TCP spojení na server více než 3 minuty neprojde žádný příkaz, server do něj pošle testovací paket, na který klientská Oracle knihovna odpoví. A pokud neodpoví, Oracle vezme spojení za mrtvé, korektně ukončí session (žádné „SNIPED“ stavy), rollbackne transakce a odemkne zámky.
Vedlejším efektem je malý nárůst síťového provozu (posílání testovacích paketů), ale za odstranění problémů se zamčenými a nedostupnými záznamy to stojí, ne?
Keywords: Oracle, DBA, locked record, session timeout