Jsem opravdu zmatený, jak strávit skutečnost, že transakce je atomová. Pokud je transakce nastavena na „dotazy“, jak bude atomová. Vztahuji slovo „dotazy“ k obecnému dotazu SQL. Transakce se proto nestane ničím jiným než sadou dotazů SQL provedených současně. Ale skutečnost, že každý dotaz více operací, opravdu nedostávám, jak se dříve provedené dotazy (ve stejné sadě) vrátí, pokud dojde k chybě v pozdějším dotazu. Co mi tady chybí? Děkujeme!
Odpověď
TL; DR; Protokol transakcí obsahuje všechny informace potřebné k opětovnému vytvoření nebo vrácení každé transakce, v závislosti na tom, zda obsahuje záznam potvrzení pro danou transakci či nikoli.
V databázích SQL se atomická transakce implementuje nejčastěji pomocí protokolování dopředu (to znamená, že položky protokolu transakcí jsou zapsány před aktualizací skutečných tabulek a indexů).
Dotazy v přísném slova smyslu, tj. SELECT
příkazy a další operace čtení, které nezmění stav databáze, nejsou protokolovány, protože není co zavázat nebo vrátit zpět, a koncept atomicity zde tedy ve skutečnosti neplatí, alespoň na úrovni DBMS. Je možné, že výsledky dotazu náročné na aplikaci budou muset vynutit atomicitu vyřazením výsledků předchozích dotazů, pokud jeden z následujících dotazů selže a způsobí vrácení zpět.
Když příkazy DML (INSERT
, UPDATE
, DELETE
, MERGE
) a další příkazy, které mění stav databáze, získají provedené změny se nejprve zapíší do protokolu WAL (Write-ahead log). Pokud jsou všechny příkazy úspěšné a je vydán závazek (explicitní nebo implicitní), je tato skutečnost zaznamenána také ve WAL a protokol je přetrváván. Díky tomu jsou změny odolné. Mohou být zapsány do skutečných segmentů tabulky a indexu někdy později, během kontrolního bodu nebo přehrávání záznamu.
Pokud by však jeden z příkazů selhal, nebyl by v záznamu žádný záznam potvrzení tato transakce a systém DBMS zruší dosud provedené změny tabulek a indexů pomocí předchozích záznamů protokolu dané transakce.
Podobně, pokud dojde k selhání procesu DBMS nebo k výpadku napájení, nebude možné záznam o potvrzení transakce za letu a změny tabulky nebo indexu, které již mohly být trvalé, budou během přehrávání záznamu vráceny zpět.
Komentáře
- Toto není ' správné: " Dotazy v přísném slova smyslu, tj. příkazy SELECT a další operace čtení. které nemění stav databáze, nejsou protokolovány, protože není nic, co by se dalo spáchat nebo vrátit zpět " – v závislosti na nastavení databáze může dokonce i SELECT spustit implicitní tr útok. brentozar.com/archive/2018/02/…
- I ' neříkám, že ' nejsou pod kontrolou transakcí, říkám to ' protože jsou nic nemění, nejsou protokolovány.
Odpovědět
Transakce je atomová, když je zapouzdřena jako toto:
BEGIN TRAN UPDATE dbo.Users SET Reputation = Reputation + 1 WHERE Id = 26837; UPDATE dbo.Posts SET Score = Score + 1 WHERE Id = 227563; COMMIT
V takovém případě se obě aktualizace ve dvou samostatných tabulkách zaváže společně nebo se společně vrátí (selžou). Atomicita znamená toto je nejmenší jednotka transakce, která bude spáchána.
Pokud se však později pokusíte spustit samostatný dotaz mimo tento rozsah, bude to samostatná transakce.
Pokud zkusíte něco takového:
BEGIN TRAN UPDATE dbo.Users SET Reputation = Reputation + 1 WHERE Id = 26837;
A pak ve své aplikaci provádíte jiné druhy prací, například kód C #, a pak se vrátíte do databáze později a udělejte toto:
UPDATE dbo.Posts SET Score = Score + 1 WHERE Id = 227563; COMMIT
Pak jak dřívější aktualizace uživatelů, tak vaše následné aktualizace příspěvků uspějí nebo selžou společně.
Ve skutečném životě však nemůžete transakci otevřít jako že po delší dobu, protože budete blokovat další lidi v práci v databázi. Proto často uvidíte rady jako: „Udržujte svou transakci krátkou a sladkou,“ což znamená, vstupte, dokončete svou práci a vraťte se zpět. Transakce výslovně neotevírejte.
Komentáře
- Transakce je vždy atomická, není ' ne?
- Ano, ale v závislosti na nastavení databáze můžete mít zapnuté implicitní transakce – to znamená, že ' znovu získání ZAČÁTEK TRAN, i když o to ' nepožádáte. To se liší podle dodavatele – například slyším výchozí nastavení Oracle na implicitní transakce, zatímco SQL Server nikoli.Možná si MYSLÍTE, že ' získáváte pouze jednu transakci, pokud pocházíte z prostředí Oracle, když na SQL Serveru můžete dostávat několik různých transakcí – každá z nich by byla atomová.