Cosa succede se non esegui il commit di una transazione su un database (ad esempio, SQL Server)?


108

Supponiamo che io abbia una domanda:

begin tran
-- some other sql code

E poi mi dimentico di impegnarmi o di tornare indietro.

Se un altro client tenta di eseguire una query, cosa succederebbe?

Risposte:


148

Finché non COMMIT o ROLLBACK una transazione, è ancora "in esecuzione" e potenzialmente con blocchi.

Se il client (applicazione o utente) chiude la connessione al database prima di eseguire il commit, tutte le transazioni ancora in esecuzione verranno annullate e terminate.


1
mmm, ok, immagino che questo stesse creando una sorta di blocco. Non ero sicuro che chiudere la connessione mi avrebbe effettivamente portato fuori da questo stato. il problema era che stavo ottenendo un errore quando ho provato a eseguire il commit. ora ho chiuso la connessione e tutto ha funzionato.
Charbel

12
Nota a margine: se si utilizza Management Studio, la chiusura della finestra della query chiuderà la connessione
Joe Phillips

3
@BradleyDotNET: sì, decisamente
marc_s

2
Tieni presente che SQL Server Management Studio esegue automaticamente il commit se chiudi la finestra / connessione della query, per impostazione predefinita.
Nuno

1
Si noti che quando il client chiude la connessione mentre una transazione è attiva, non viene sempre eseguito il rollback: questo dipende dal client e dal database. Ad esempio, quando un'app Java chiude una connessione a un database Oracle, tutte le connessioni aperte vengono automaticamente salvate.
AVID

38

Puoi effettivamente provarlo da solo, questo dovrebbe aiutarti a farti un'idea di come funziona.

Aprire due finestre (schede) in Management Studio, ognuna di esse avrà la propria connessione a sql.

Ora puoi iniziare una transazione in una finestra, fare alcune cose come inserire / aggiornare / eliminare, ma non ancora eseguire il commit. quindi nell'altra finestra puoi vedere come appare il database dall'esterno della transazione. A seconda del livello di isolamento, la tabella potrebbe essere bloccata fino al commit della prima finestra, oppure potresti (non) vedere cosa ha fatto l'altra transazione fino a quel momento, ecc.

Gioca con i diversi livelli di isolamento e nessun suggerimento di blocco per vedere come influenzano i risultati.

Guarda anche cosa succede quando lanci un errore nella transazione.

È molto importante capire come funzionano tutte queste cose o rimarrai perplesso da ciò che fa sql, molte volte.

Divertiti! GJ.


ok ma la transazione verrà scritta nel log almeno prima di emettere il commit? Ad esempio, diciamo che voglio avviare una transazione, eseguire un comando di inserimento e "fare qualcos'altro" prima di eseguire il commit. il mio comando di inserimento verrà scritto nel log? in questo modo se il server si arresta in modo anomalo prima di eseguire il commit, può tornare al punto in cui si trovava e posso semplicemente emettere il commit in un secondo momento (ogni volta che ho finito di fare "qualcos'altro").
user1870400

16

Le transazioni sono destinate a essere eseguite completamente o per niente. L'unico modo per completare una transazione è eseguire il commit, qualsiasi altro modo comporterà un rollback.

Pertanto, se si inizia e poi non si esegue il commit, verrà eseguito il rollback alla chiusura della connessione (poiché la transazione è stata interrotta senza essere contrassegnata come completa).


È così che dovrebbe essere, ma non è sempre così.
FalcoGer

... come MyISAM di mySQL, che non supporta le transazioni, certo.
Piskvor ha lasciato l'edificio il

3

dipende dal livello di isolamento della transazione in entrata.

Spiegazione dell'isolamento delle transazioni SQL


6
Il comportamento delle transazioni non dipende dal livello di isolamento. La quantità di serrature che potrebbero causare fa.
marc_s

Sono abbastanza sicuro che i dati che possono essere letti da una connessione dipendono sicuramente dal livello di isolamento. Se l'isolamento è impostato su READ UNCOMMITTED, è possibile leggere i dati non ancora salvati e potrebbero in effetti essere ripristinati a un certo punto della traccia, ma questo garantisce che non vi sia alcun blocco. Se hai READ COMMITTED come livello di isolamento, non puoi leggere le righe non salvate: il secondo client si bloccherà a meno che tu non usi SNAPSHOT.
Xhalent

2

Quando apri una transazione nulla viene bloccato da solo. Ma se esegui alcune query all'interno di quella transazione, a seconda del livello di isolamento, alcune righe, tabelle o pagine vengono bloccate, quindi influirà su altre query che tentano di accedervi da altre transazioni.


1

Esempio di transazione

inizio tran tt

Le tue dichiarazioni sql

se si è verificato un errore, eseguire il rollback tran tt, altrimenti eseguire il commit

Finché non si è eseguito il commit tran tt, i dati non verranno modificati


1
Si noti che la denominazione delle transazioni non solo non è necessaria in MS SQL, ma può dare un falso senso di controllo. BEGIN TRAN X ... BEGIN TRAN Y ... ROLLBACK Ynon funziona, per esempio. Vedere stackoverflow.com/questions/1273376/...

0

Oltre ai potenziali problemi di blocco che potresti causare, scoprirai anche che i tuoi registri delle transazioni iniziano a crescere poiché non possono essere troncati oltre l'LSN minimo per una transazione attiva e se stai usando l'isolamento dello snapshot il tuo archivio delle versioni in tempdb crescerà per ragioni simili.

È possibile utilizzare dbcc opentranper visualizzare i dettagli della transazione aperta più vecchia.


0

Qualsiasi transazione non eseguita lascerà il server bloccato e altre query non verranno eseguite sul server. È necessario eseguire il rollback della transazione o eseguirne il commit. La chiusura di SSMS terminerà anche la transazione che consentirà l'esecuzione di altre query.


-4

Il comportamento non è definito, quindi è necessario impostare esplicitamente un commit o un rollback:

http://docs.oracle.com/cd/B10500_01/java.920/a96654/basic.htm#1003303

"Se la modalità di commit automatico è disabilitata e chiudi la connessione senza eseguire esplicitamente il commit o il rollback delle ultime modifiche, viene eseguita un'operazione COMMIT implicita."

Hsqldb esegue un rollback

con.setAutoCommit(false);
stmt.executeUpdate("insert into USER values ('" +  insertedUserId + "','Anton','Alaf')");
con.close();

il risultato è

2011-11-14 14: 20: 22,519 INFO principale [SqlAutoCommitExample: 55] [AutoCommit enabled = false] 2011-11-14 14: 20: 22,546 INFO principale [SqlAutoCommitExample: 65] [Trovato 0 # utenti nel database]


2
Questo potrebbe essere vero per Oracle (non ne ho idea), ma l'interrogante chiede informazioni su MS-SQL
PaulG

La prima citazione si applica al driver JDBC, non al server.
Djechlin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.