Kolize při ukládání do databáze (transakce, zamykání, object version)
V některých situacích může docházet k tzv. kolizím při ukládání dat. Ke kolizím může dojít z mnoha příčin. Např. pokud dva uživatelé současně vykonají tutéž činnost, např. se pokusí opravit týž záznam, nebo, pokud se uživatel pokusí opravit záznam v
Pesimistický přístup:
Jedná se o tzv. "zamykání" záznamů. Tato technologie sice předchází vzniku kolizí (není třeba řešit situaci, kdy dva uživatelé najednou se pokouší měnit tentýž záznam), ale na druhou stranu omezuje uživatele (po dobu opravy je záznam uzamčen a uživatel musí čekat na uvolnění), a proto se také někdy označuje jako "pesimistický přístup". Objasníme na velmi jednoduchém příkladu:
Příklad 1: Mějme uživatele Nováka a Bláhu, pracující v síťové instalaci IS. Dále nadefinované středisko 100 s názvem Obchod a ulicí Dlouhá 50. Uživatel Novák chce provést opravu střediska 100, a to jeho názvu, a uživatel Bláha chce z nějakého důvodu provést opravu téhož střediska 100, a to jména ulice. Novák zahájí opravu střediska 100. V ten moment dojde k zamčení záznamu střediska v databázi. Pokud Bláha chce zahájit opravu, systém oznámí, že to nelze, jelikož záznam je uzamčen a opravu nepovolí. Bláha musí počkat až Novák svou opravu ukončí a záznam uvolní.
Optimistický přístup:
V systému IS FLORES se používá jiný přístup. Jak bylo uvedeno v kapitole o technologii zpracování dat, jedná se o databázový klient/server systém, pracující na principu tzv. transakcí (tj. je zahájena nějaká transakce s cílem provést požadovanou akci, např. uložit změny v záznamu (start transakce), poté transakce probíhá a, pokud se ji podaří provést, je úspěšně ukončena, neboli potvrzena (commit transakce), anebo, pokud se ji nepodaří úspěšně provést (došlo k nějaké kolizi, např. nelze uložit data daného záznamu, jelikož byl změněn současně v rámci jiné transakce, či je blokován jinou transakcí), není transakce potvrzena a vše se vrátí zpět do stavu před jejím zahájením (rollback transakce).
V takovýchto systémech se většinou nepoužívá zahajování transakcí ihned při zahájení manipulace se záznamem, např. vyvolání funkce Oprava (protože oprava záznamu by teoreticky mohla trvat i velmi dlouho, přičemž po celou tu dobu by musela být zahájena transakce a podpora dlouho trvajících transakcí není u SQL databází obvyklá).
V IS FLORES se tedy transakce ve většině případů zahajuje až v okamžiku ukládání. Uživatelsky to např. znamená, že je možno zahájit stejnou operaci se stejným záznamem a teprve při ukládání se kontrolují a řeší případné kolize. Tato technologie sice nepředchází vzniku kolizí, ale na druhou stranu uživatele nijak neomezuje, a proto se někdy označuje jako "optimistický přístup". Vzniklou kolizi objasníme na tomtéž příkladu:
Příklad 2: Uživatel Novák i Bláha zahájí opravu střediska 100, Novák změní název střediska na Obchod celkem (ulici nemění) a Bláha změní ulici na Jirskou 475 (název střediska nemění). Novák záznam uloží, zahájí se a úspěšně potvrdí příslušná transakce, stav v databázi tedy je "středisko 100, Obchod celkem, Dlouhá 50". Poté chce uložit Bláha. Zahájí se transakce. Systém ale zjistí, že záznam střediska byl mezitím, co Bláha opravoval ulici, změněn a nahlásí kolizi (nemůže sám o sobě rozhodnout, jak pokračovat, zda ponechat změnu názvu provedenou Novákem, anebo data, která má Bláha, tj. původní název a novou ulici. Systém transakci zruší, akce uložení se neprovede.
Řešení takových kolizí je různé a závisí na jejich konkrétním typu.
Simulace pesimistického zamykání:
V některých provozech ale dochází často k situacím, kdy dva uživatelé začnou opravovat v jeden okamžik tentýž záznam. Při výše popsaném optimistickém přístupu dojde ke kolizi, tedy jeden z uživatelů nebude moci své údaje uložit a o provedené změny přijde, bude je muset zadat znovu (podrobněji viz dále Kolize při změně ObjectVersion). To je nepříjemné zejména v případech dlouhotrvajících editací rozsáhlých záznamů (např. nekolikařádkových dokladů). Aby se mohlo v těchto případech kolizím předcházet, systém umožňuje simulaci pesimistického zamykání.
Zapíná se pomocí parametru PessimisticEditLock, který musí být uveden v souboru nexus.cfg v sekci [Client]. Je-li simulace pesimistického zamykání zapnuta, pak je po vyvolání opravy záznamu opravovaný záznam uzamknut a dalšímu uživateli je při pokusu o opravy sděleno, že musí počkat než skončí editace dokladu u prvního uživatele.
Příklad hlášení při pokusu o paralelní editaci téhož dokladu, je-li zapnuta simulace pesimistického zamykání
Platí:
- Zamykání je prováděno pouze přes uživatelské rozhraní systému IS FLORES
- Kontrola se vztahuje i na hromadné opravy. Tj. pokud je rozeditován záznam a někdo se pokouší použít hromadnou opravu nebo hromadnou opravu uživatelských položek téhož záznamu, je na uzamknutí záznamu upozorněn a daný záznam není hromadnou opravou nijak změněn.
- Toto "pesimistické" zamykání je pouze pomůckou v situacích, které běžně nastávají, kdy se uživatelé občas "potkávají" při běžné opravě téhož dokladu nebo záznamu v číselníku. Nic dalšího neřeší. Čili:
- Vztahuje se pouze na funkci Opravit v dokladových a číselníkových agendách. Není tedy např. implementováno v agendách jako jsou Firemní údaje, Nastavení parametrů mezd, Definice klíčů.
- Není hlídána změna záznamu provedená jiným způsobem, např.:
- Aktivity - funkce Předat
- Zakázky, Obchodní případy, Projekty - funkce Uzavřít/Otevřít
- Odeslaná pošta - funkce Uzávěrka
- apod.
- Nijak se nehlídá případné smazání uzamknutého dokladu provedené jiným uživatelem.
Princip kontroly, zda došlo ke kolizi
IS FLORES si u každého záznamu v databázi (např. záznam střediska), pamatuje jednak jeho interní identifikátor ( "ID") a dále číslo verze tohoto záznamu ( tzv. "ObjectVersion", budeme jej označovat "OV"). Pokud dojde ke změně záznamu, systém automaticky v databázi zvyšuje číslo verze. Podle tohoto čísla se pak rozpoznává, zda byl objekt změněn či nikoli.
Ke kolizím tedy může dojít:
- při běhu v síťové instalaci
- při běhu ve dvou oknech
- ale i při běhu v jednom okně při otevření téže agendy vícekrát
Objasníme na příkladu:
Příklad 3: Mějme otevřenu agendu faktur vydaných ve dvou oknech. V obou v záložce Omezení provedeme dotaz a načteme fakturu FV-100. Tato faktura nechť má ID=ABC345 a OV=1 (ve skutečnosti vypadá jinak). V prvním okně provedeme opravu faktury a uložíme. V ten moment se zvýší číslo verze, tedy OV=2. V druhém okně provádíme opravu téže faktury a uložíme. Systém porovnáním verzí zjistí, že se pokoušíme uložit "starší" záznam s OV=1, který byl mezitím změněn. Nahlásí kolizi.
Vznik takové kolize můžeme rovněž objasnit i na následujícím zjednodušeném schématu. Modrá barva znázorňuje stav dat dvou současně pracujících uživatelů, červená stav v databázi. Písmena S/C/R demonstrují S=start, C=commit a R=rollback transakce. V databázi nechť je záznam s ObjectVersion OV=1. Uživatel 1 zahájí operaci oprava záznamu. Tudíž zahájí a ukončí se transakce, v rámci níž se načtou data z databáze (select), záznam má OV=1. Poté uživatel 1 provádí požadované změny. Mezitím Uživatel 2 zahájí opravu téhož záznamu (což může, jelikož daný záznam není prvním uživatelem nijak uzamčen, tj. i jemu se provede v rámci krátké transakce select z databáze, záznam má stále OV=1. Poté Uživatel 1 vyvolá uložení svých oprav do databáze. Zahájí se pro něj transakce, v rámci níž se provede uložení dat (update) a která úspěšně proběhne. Po jejím potvrzení bude mít záznam v databázi OV=2. Pokud poté druhý uživatel vyvolá uložení svých oprav, zahájí se i jemu transakce pro uložení dat do databáze (update), ale tato skončí neúspěšně, jelikož se mezitím změnil ObjectVersion. Uživateli 2 se provede nový select z databáze (
Zjednodušený schématický náčrt průběhu transakcí dvou současně pracujících uživatelů.Transakce 1,2 a 3 proběhly úspěšně (naznačeno barevnou výplní) a byly potvrzeny (commit). Transakce 4 neproběhla úspěšně a byl proveden rollback.
Kolizím tohoto typu lze většinou předcházet průběžným prováděním
Tím se tedy případy vzniku kolizí minimalizují, nicméně i přes to k nim může dojít. Případům, kdy dva uživatelé rozeditují jeden a tentýž záznam, lze bránit simulací pesimistického zamykání, viz výše.
Většina kolizí tohoto typu vyžaduje interakci uživatele. Tj. pokud dojde při ukládání ke kolizi, jelikož záznam byl změněn jiným uživatelem nebo i týmž uživatelem z jiné spuštěné úlohy IS FLORES případně z agendy spuštěné v samostatném okně apod. a neproběhl
Příp. program uživateli oznámí, že z databáze byla načtena nová data (aktuální stav z databáze) a uživatel musí své změny zadat a uložit znovu.
Speciálně ošetřené situace - Nicméně jsou v systému případy, kdy takové situace jsou speciálně ošetřeny, např. při pokusu dvou uživatelů současně provést pohyb na té
Zjednodušený schématický náčrt průběhu transakcí a pokusu systému změny uživatele 2 uložit, přestože se díky zásahu jiného uživatele mezitím změnil OV záznamu v databázi (navazuje na předchozí schéma, viz výše). Transakce 4 neproběhla úspěšně (viz předchozí schéma). Následuje časový interval, v němž se systém opakovaně pokusí o uložení, tj. načte aktuální stav, zaznamená změnu a pokusí se uložit (transakce 5 a 6).
Kolize při pokusu o uložení mohou nastat nejen v případě, že byl současně změněn týž záznam (současná změna ObjectVersion), jak bylo řečeno výše, ale i v případě, že se pokoušíme uložit záznam s odkazem na jiný záznam aktuálně "držený" nějakou jinou transakcí.
Jak plyne ze schématických obrázků výše, většina transakcí prováděných v IS FLORES je velmi krátkých, a tudíž je u nich pravděpodobnost vzniku takovýchto kolizí velmi malá. Nicméně existují v systému i případy, kdy akce probíhá v rámci jedné dlouho trvající transakce (uzávěrka skladu, zálohování dat apod.).
Pokud se v rámci nějaké dlouhotrvající transakce pracuje s nějakým objektem, a uživatel se mezitím pokusí o uložení záznamu, který se na tentýž objekt odkazuje, pokus o uložení selže.
Příkladem může být právě uzávěrka skladu, která mění objekt sklad. Jelikož však trvá dlouho, je objekt sklad delší dobu nedostupný pro použití z následných transakcí. (Databáze nemůže povolit uložit záznam odkazující se na takový objekt, jelikož předchozí transakce jej může obecně třeba i smazat či změnit jeho interní identifikátor, přes který se realizuje odkaz apod., tudíž při pokusu o uložení databáze čeká a, pokud se v rámci určitého časového intervalu nedočká, pak oznámí chybu.):
Zjednodušený schématický náčrt pokusu o uložení změn s odkazem na objekt sklad "držený" transakcí skladová uzávěrka. Transakce 3 neproběhne úspěšně, ačkoliv se samotný ObjectVersion objektu sklad během změn provedených uživatelem 2 nezměnil a je stále 2.
Transakce se "zjednodušeně řečeno" ukládají po ukončení akce v pořadí, v jakém byly zahájeny (myslí se transakce zahájené v daném "connectionu" na databázi). Přičemž pokud jedna transakce není ukončena, nelze uložit ani následující. Proto, pokud probíhá nějaká transakce, nelze se přepnout v rámci dané spuštěné úlohy IS FLORES do jiné agendy (a to ani otevřené v jiném samostatném okně, i když by šlo o jiný samostatný "connection" na databázi), aby v rámci dané spuštěné úlohy IS FLORES nedocházelo zbytečně ke kolizím (pokud by z nějakého důvodu po ukončení např. akce uzávěrky nebyla ukončena transakce uzávěrky, nebylo by možno uložit ani případné transakce, které byste provedli poté).
V průběhu dlouho trvajících transakcí může docházet v systému ke změnám jedině tehdy, pokud systém provozujete síťově a změnu provádíte z jiné spuštěné úlohy IS FLORES.
Pokud spustíte nějakou časově náročnou akci a současně chcete pracovat v jiné agendě, pak si musíte spustit požadovanou agendu v rámci druhé spuštěné úlohy IS FLORES (síťově).
Dále zde zmíníme případ zálohování, které je jednou z dlouho trvajících transakcí. Při zálohování platí, že do zálohy se zahrnou JEN ta data, která byla pořízena v okamžiku zahájení transakce zálohování. Tedy, pokud byste v průběhu zálohování např. opravili nějaký doklad, vystavili nový apod., daná změna nebo nový doklad v záloze obsažen nebude! A to ani v případě, že byste tuto změnu provedli ještě dříve, než přijde "na řadu" zálohování tabulky databáze, v níž byla daná změna provedena!