Sono davvero confuso su come digerire il fatto che una transazione sia atomica. Se una transazione è un insieme di “query”, allora come sarà atomica. Metto in relazione la parola “query” con una query SQL generale. Pertanto una transazione diventa quindi nientaltro che un insieme di query SQL eseguite contemporaneamente. Ma il fatto che ogni query sia più operazioni, non riesco davvero a capire come le query eseguite in precedenza (nello stesso set) ripristinano se si verifica un errore in una query successiva. Cosa mi manca qui? Grazie!
Risposta
TL; DR; Il log delle transazioni contiene tutte le informazioni necessarie per ricreare o annullare ogni transazione, a seconda che contenga o meno un record di commit per quella transazione.
Nei database SQL latomicità delle transazioni viene implementata più frequentemente utilizzando registrazione write-ahead (il che significa che le voci del log delle transazioni vengono scritte prima che le tabelle e gli indici effettivi vengano aggiornati).
Query nel senso stretto della parola, ovvero SELECT
le istruzioni e altre operazioni di lettura che non cambiano lo stato del database, non vengono registrate poiché non cè nulla da salvare o ripristinare, e come tale il concetto di atomicità non si applica realmente qui, almeno a livello di DBMS. Lapplicazione che utilizza i risultati delle query potrebbe dover applicare latomicità scartando i risultati delle query precedenti se una delle query successive fallisce e causa il rollback.
Quando le istruzioni DML (INSERT
, UPDATE
, DELETE
, MERGE
) e altre istruzioni che modificano lo stato del database ottengono eseguito, le modifiche apportate vengono prima scritte nel registro write-ahead (WAL). Se tutte le istruzioni hanno esito positivo e viene emesso un commit (esplicito o implicito), anche questo fatto viene registrato nel WAL e il log viene mantenuto. Ciò rende le modifiche durevoli. Possono essere scritti nella tabella e nei segmenti di indice effettivi in un secondo momento, durante un checkpoint o una riproduzione del log.
Tuttavia, se una delle istruzioni fallisce, non ci sarebbe alcun record di commit nel log per questa transazione e il DBMS annullerà le modifiche alla tabella e allindice apportate finora utilizzando i precedenti record di log di quella transazione.
Allo stesso modo, se il processo DBMS si interrompe o si interrompe lalimentazione, non ci sarà un record di commit per la transazione in volo e le modifiche alla tabella o allindice che potrebbero essere già state rese persistenti verranno annullate durante la riproduzione del registro.
Commenti
- Questo non è ' corretto: " Query nel senso stretto della parola, ovvero istruzioni SELECT e altre operazioni di lettura che non cambiano lo stato del database, non vengono registrati perché non cè nulla da salvare o ripristinare " – a seconda delle impostazioni del database, anche un SELECT può avviare un tr implicito ansazione. brentozar.com/archive/2018/02/…
- I ' non dico che ' non è sotto il controllo delle transazioni, io ' lo dico, poiché lo sono non cambiano nulla, non vengono registrati.
Risposta
Una transazione è atomica quando è incapsulata come questo:
BEGIN TRAN UPDATE dbo.Users SET Reputation = Reputation + 1 WHERE Id = 26837; UPDATE dbo.Posts SET Score = Score + 1 WHERE Id = 227563; COMMIT
In tal caso, entrambi gli aggiornamenti sulle due tabelle separate verranno impegnati insieme o verranno ripristinati (falliti) insieme. Atomicità significa questa è lunità più piccola di una transazione su cui verrà eseguito il commit.
Tuttavia, se in seguito, provi a eseguire una query separata al di fuori di tale ambito, sarebbe una transazione separata.
Se provi qualcosa del genere:
BEGIN TRAN UPDATE dbo.Users SET Reputation = Reputation + 1 WHERE Id = 26837;
E poi nella tua applicazione, fai altri tipi di lavoro, come il codice C #, e poi torni al database in seguito e procedi in questo modo:
UPDATE dbo.Posts SET Score = Score + 1 WHERE Id = 227563; COMMIT
Quindi sia il precedente aggiornamento degli utenti che il successivo aggiornamento dei post riusciranno o falliranno insieme.
Tuttavia, nella vita reale, non puoi tenere aperta una transazione come questo per un lungo periodo di tempo perché impedirai ad altre persone di lavorare nel database. Questo è il motivo per cui vedrai spesso consigli come “Mantieni la tua transazione breve e dolce”, ovvero, entra, porta a termine il tuo lavoro e torna indietro. Non tenere esplicitamente aperte le transazioni.
Commenti
- Una transazione è sempre atomica, non è ' vero?
- Sì, ma a seconda delle impostazioni del database, potresti avere le transazioni implicite attivate, ovvero ' re ottenere un BEGIN TRAN anche se non ' lo richiede. Ciò varia a seconda del fornitore, ad esempio, sento che Oracle utilizza per impostazione predefinita le transazioni implicite, mentre SQL Server no.Potresti PENSARE che ' stai ricevendo una sola transazione se provieni da un background Oracle, quando potresti ricevere diverse transazioni diverse in SQL Server, ognuna delle quali sarebbe atomica.