Ztracené aktualizace (English ztratil aktualizace ) je typ chyby, které se mohou objevit v počítači při psaní vícenásobný přístup ke sdíleným informacím obsaženým v souběžně. Když dvě transakce upraví stejné informace, úpravy první mohou být okamžitě překryty úpravami druhé, pokud nebudou přijata žádná opatření proti tomuto problému; aktualizace provedené první transakcí jsou údajně ztraceny .
K tomuto problému může dojít bez ohledu na formu sdílené informace trvá, ať už je to v souboru , v databázové tabulce nebo v paměti sdílené mezi více vlákny . Tento problém se také liší od problému poškození dat, ke kterému může dojít při špatně synchronizovaných zápisech, ačkoli řešení obou problémů často používají stejné základní mechanismy.
Počítačový systém kina (kde místa nejsou očíslovaná) ukládá počet již prodaných vstupenek na promítání. 100 vstupenek již bylo prodáno a Cashier # 2 je v procesu prodeje dalších tří. Pokladník č. 1 současně zaznamená náhradu pěti lístků, kterou je proto třeba odečíst od celkové částky. Pokladní systém č. 1 proto odečte 5 od celkového počtu lístků (100), a proto do databáze vloží 95. Bezprostředně poté pokladník č. 2 zaznamená svou vlastní transakci a přidá 3 k počtu bankovek, které si sám zapamatoval , tj. 103, a zapíše výsledek do základny. První aktualizace je proto ztracena a konečný výsledek je nepravdivý (103 místo 98 skutečně obsazených míst).
Krok | Pokladna 1: refundace 5 lístků |
Počet prodaných vstupenek uložených v databázi | Pokladna 2: prodej 3 lístků |
---|---|---|---|
0 | 100 | ||
1 |
Přečtěte si počet prodaných vstupenek
Výsledek: 100 |
100 | |
2 | 100 |
Přečtěte si počet prodaných vstupenek
Výsledek: 100 |
|
3 | Vraťte 5 lístků
Vypočítejte novou hodnotu: 100-5 = 95 Napište novou hodnotu (95) |
95 | |
4 | 103 | Prodejte 3 lístky
Vypočítejte novou hodnotu: 100 + 3 = 103 Napište novou hodnotu (103) |
Nejjednodušším řešením problému ztracené aktualizace není rozdělit operace čtení a zápisu, jak jsme to udělali v pseudokódu pokladen z předchozího příkladu; místo toho použijeme atomovou operaci, která čte a zapisuje například do databáze SQL :
UPDATE salles SET nb_places = nb_places + 5 WHERE numero_salle = 4;Atomový řešení úprava neplatí, když se klient programu na DBMS má právo provádět komplexně rozhodovat na základě dat, která čte před provedením své zápisy. K vyřešení problému ztracené aktualizace v této souvislosti je nutné použít mechanismus uzamčení dat, který zabrání více než jednomu programu v úpravě sdílených dat. Relevantní primitivní zajišťovací mechanismy jsou následující:
Tyto mechanismy jsou poskytovány všemi obvyklými datovými systémy:
V případě transakčních databází se o problém ztracené aktualizace častěji postará přímo DBMS, jak uvidíme později.
Tady je tok transakcí ve výše uvedeném příkladu, když používáte exkluzivní zámek:
Krok | Pokladna 1: refundace 5 lístků |
Přepravka 1: zámek držen |
Počet prodaných vstupenek uložených v databázi | Přepravka 2: zámek držen |
Pokladna 2: prodej 3 lístků |
---|---|---|---|---|---|
0 | 100 | ||||
1 | Požádejte o exkluzivní zámek | Výhradní | 100 | ||
2 | Výhradní | 100 |
Požádejte o exkluzivní zámek
(Blokováno...) |
||
3 |
Přečtěte si počet prodaných vstupenek
Výsledek: 100 |
Výhradní | 100 | ||
4 | Vraťte 5 lístků
Vypočítejte novou hodnotu: 100-5 = 95 Napište novou hodnotu (95) |
Výhradní | 95 | ||
5 | Zámek zámku | 95 | Výhradní | (... Odemčeno!) | |
6 | 95 | Výhradní |
Přečtěte si počet prodaných vstupenek
Výsledek: 95 |
||
7 | 98 | Výhradní | Prodejte 3 lístky
Vypočítejte novou hodnotu: 95 + 3 = 98 Napište novou hodnotu (98) |
||
8 | 98 | Zámek zámku |
Hlavní nevýhodou metody zámku je, že je volitelná : spoléhá se na ochotu zúčastněných transakcí získat a uvolnit zámky ve správný čas, jinak by mohlo dojít ke ztrátě aktualizací nebo dokonce závažnějším problémům, jako je poškození dat. Kromě toho je výlučný zámek potenciálním úzkým místem , protože musí být držen v době, kdy trvají výpočty transakce a komunikace se základnou. To v kině nepochybně není problém, ale může se stát problémem pro složitější systémy, zejména pokud jsou rozmístěny na několika místech po celém světě.
Standard SQL92 definuje funkci známou jako úrovně izolace , což je pro databázi řešení problému ztracených aktualizací na straně serveru . Pro výše uvedené případy ticketingu algoritmů stačí úroveň izolace „read repeatable“ ( opakovatelné čtení ). Zde jsou příkazy SQL potřebné pro PostgreSQL , který nemá izolační úroveň „opakovatelného čtení“ (takže místo toho používáme „serializovatelný“, který je silnější):
BEGIN WORK SET TRANSACTION ISOLATION LEVEL SERIALIZABLE SELECT nb_places FROM salles WHERE no_salle = 4 -- Ici intervient le calcul du nombre de places restantes -- par la caisse UPDATE nb_places SET nb_places = 98 WHERE no_salle = 4 END WORKDatabázový server se může rozhodnout přeložit příkaz SET TRANSACTION ISOLATION LEVEL SERIALIZABLEzískáním exkluzivního zámku pro celou databázi; pak se ocitneme v situaci předchozího odstavce. To není to, co PostgreSQL dělá; dovedněji to umožní paralelní čtení (příkazy SELECT) a odmítne zápisy (způsobí vrácení transakce), pokud je zjištěna situace ztracené aktualizace. Tímto způsobem PostgreSQL umožňuje, aby transakce zahrnující různá data probíhaly úplně paralelně, a zakazuje ztracené aktualizace bez nutnosti důvěřovat klientům, aby správně zvládli složitost zamykání; Nevýhodou je, že existuje riziko svévolného vrácení peněz , a pokladník musí být proto připraven opakovat svoji transakci (v případě potřeby několikrát), dokud nebude úspěšná.
Myšlenka opakování transakce několikrát není obvykle přijatelná, pokud se jedná o lidského uživatele: ve skutečnosti by uživatel musel pokaždé znovu spustit veškerou svou práci se zadáváním dat. Řešení jsou následující: