Qual è l'effetto di avere una transazione aperta in MSSQL per troppo tempo?


11

Mi chiedo solo cosa succede se si avvia una transazione in un DB e si è dimenticato di eseguire il commit o il rollback. Il server sarà inattivo? Diciamo che l'hai lasciato per 3 giorni.

Ci sono anche utenti che lo usano supponendo che gli altri utenti non sapessero che esiste una transazione non chiusa (supponiamo che gli utenti stiano semplicemente inserendo dati nel database). Quali sono le conseguenze di questa azione?

Risposte:


14

Avere una transazione aperta da sola non avrà quasi conseguenze. Un semplice

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

nel peggiore dei casi conterrà alcuni byte di valori di stato. Nessun grosso problema.

La maggior parte dei programmi eseguirà il lavoro effettivo all'interno della transazione e questa è un'altra questione. Il punto di una transazione è che puoi essere sicuro che diversi fatti all'interno del database sono veri simultaneamente, nonostante ci siano altri utenti che scrivono nello stesso database contemporaneamente.

Prendi l'esempio canonico del trasferimento di denaro tra conti bancari. Il sistema deve garantire che l'account di origine esista, abbia fondi sufficienti, che esista l'account di destinazione e che si verifichino debiti e crediti o che non si verifichino. Deve garantire questo mentre avvengono altre transazioni, forse anche tra questi due conti. Il sistema garantisce ciò prendendo i blocchi sui tavoli interessati. Quali blocchi vengono presi e quanta parte del lavoro di altre persone vedi è controllata dal livello di isolamento delle transazioni .

Quindi, se fai molto lavoro, ci sono buone probabilità che altre transazioni vengano messe in coda in attesa degli oggetti su cui tieni i blocchi. Ciò ridurrà il throughput complessivo del sistema. Alla fine colpiranno i limiti di timeout e falliranno, il che è un problema per il comportamento generale del sistema. Se si utilizza un livello di isolamento ottimistico, la transazione potrebbe non riuscire quando si tenta un commit a causa del lavoro di altri.

Tenere i blocchi richiede risorse di sistema. Questa è la memoria che il sistema non può utilizzare per elaborare altre richieste, riducendo la velocità effettiva.

Se è stato eseguito molto lavoro, il sistema può scegliere di eseguire l' escalation dei blocchi . Invece di bloccare singole righe, l'intera tabella verrà bloccata. Quindi saranno interessati più utenti simultanei, il throughput del sistema diminuirà ulteriormente e l'impatto dell'applicazione sarà maggiore.

Le modifiche ai dati vengono scritte nel file di registro, così come i blocchi che le proteggono. Questi non possono essere cancellati dal registro fino al completamento della transazione. Pertanto, una transazione molto lunga può causare il rigonfiamento del file di registro con i problemi associati.

Se il lavoro corrente utilizza tempdb, che è probabilmente per carichi di lavoro di grandi dimensioni, le risorse potrebbero essere legate fino alla fine della transazione. In casi estremi ciò può causare il fallimento di altre attività perché non c'è più spazio sufficiente per esse. Ho avuto casi in cui un UPDATE scarsamente codificato ha riempito tempdb, quindi non era rimasto un disco sufficiente per l'ORTO di un report e il report non è riuscito.

Se si sceglie di eseguire il ROLLBACK della transazione, o se il sistema fallisce e si ripristina, il tempo impiegato per rendere nuovamente disponibile il sistema dipenderà dalla quantità di lavoro eseguita. La semplice apertura di una transazione non influirà sui tempi di recupero, ma sulla quantità di lavoro eseguita. Se la transazione era aperta ma inattiva per un'ora il recupero sarà quasi istantaneo. Se scriveva costantemente per quell'ora, la regola empirica è che anche il tempo di recupero sarà di circa un'ora.

Come puoi vedere, le transazioni lunghe possono essere problematiche. Per i sistemi OLTP, è consigliabile disporre di una transazione di database per transazione commerciale. Per l'input del processo di lavoro batch in blocchi, con frequenti commit e codice di riavvio codificato. In genere, diverse migliaia di record possono essere elaborati all'interno di una singola transazione DB, ma questo dovrebbe essere testato per la concorrenza e ripristinare il consumo.

Non essere tentato di andare all'altro estremo ed evitare interamente transazioni e blocchi. Se hai bisogno di mantenere la coerenza con i tuoi dati (e perché altrimenti dovresti utilizzare un database?) I livelli di isolamento e le transazioni hanno uno scopo molto importante. Scopri le tue opzioni e decidi con quale equilibrio di concorrenza e correttezza sei pronto a convivere per ogni parte della tua applicazione.


anche se è aperto per tre giorni?
JanLeeYu,

Sì, anche per tre giorni. Il punto importante è la quantità di lavoro che è stato fatto mentre il TX è aperto, non solo per quanto tempo è stato aperto. Naturalmente come DBA potresti voler chiedere al proprietario della transazione perché ne hanno bisogno per essere aperto per così tanto tempo. Quando gestivo un team DBA, registravo tutti i TX aperti da più di 30 minuti e conversavo con il proprietario.
Michael Green,

OK. Grazie per l'ottima spiegazione. Anche se tutti hanno fatto un ottimo lavoro.
JanLeeYu,

Che sollievo ... Grazie ancora per la risposta.
JanLeeYu,

"AGGIORNAMENTO codificato male" Sì. Visto. Un'istruzione di aggiornamento all'interno di un ciclo che non ha qualificato alcuni nomi e ha comportato un comportamento simile a 1 = 1, quindi ha aggiornato l'intera tabella per ogni iterazione del ciclo (che ha anche inserito dati errati sulla maggior parte di quelle righe).
jpmc26,

6

La tua più grande conseguenza sarà il blocco degli oggetti utilizzati nella transazione. Soprattutto se si presume che i tuoi utenti stiano inserendo dati, quella transazione a lungo termine potrebbe includere istruzioni SELECT su tabelle di uso comune. Le dichiarazioni di aggiornamento dei tuoi utenti potrebbero non essere in grado di ottenere il blocco necessario per completare i loro aggiornamenti o inserti.

Una cosa secondaria che potrebbe accadere è l'attività del file di registro, ad esempio se si stava aggiornando un set di dati di grandi dimensioni, la parte del registro utilizzata dalla transazione viene mantenuta attiva per la durata della transazione. Non sarà possibile riutilizzare quella parte del registro fino a quando la transazione non viene impegnata o ripristinata. In scenari in cui potresti trovarti in un sistema OLTP fortemente attivo, ciò potrebbe causare la rapida crescita del file di registro, riempiendo il dispositivo di archiviazione.


ad esempio, colui che ha creato la transazione è disconnesso dal server, sarà in grado di accedere nuovamente al server per chiudere la transazione?
JanLeeYu,

Dipenderà, se la transazione fosse in un ambiente che utilizzava MSDTC, potrebbe trattarsi di una transazione orfana. In tal caso, l'utente non sarebbe più in grado di chiuderlo da solo ... il DBA dovrebbe intervenire per gestirlo. A parte ciò, in genere dovresti vedere la transazione annullata da SQL Server quando si disconnette ... ma di nuovo su transazioni di grandi dimensioni che potrebbero non essere tutte le volte.

In tal caso, l'amministratore sarà ancora in grado di chiudere la transazione, giusto?
JanLeeYu,

Non posso rispondere a quello, dipende tutto. Ho avuto casi in cui è stato necessario riavviare il server o l'istanza ha eseguito il failover sul nodo / replica secondario.

4

La transazione incompleta può contenere un numero elevato di blocchi e causare il blocco

Quando una transazione non viene completata a causa del timeout di una query o perché il batch viene annullato nel mezzo di una transazione senza emettere un'istruzione COMMIT o ROLLBACK per completare la transazione, la transazione viene lasciata aperta e tutti i blocchi acquisiti durante tale transazione continuano essere tenuto. Le transazioni successive eseguite con la stessa connessione vengono trattate come transazioni nidificate, quindi tutti i blocchi acquisiti in queste transazioni completate non vengono rilasciati. Questo problema si ripete con tutte le transazioni eseguite dalla stessa connessione fino all'esecuzione di un ROLLBACK. Di conseguenza, vengono conservati numerosi blocchi, gli utenti vengono bloccati e le transazioni vengono perse, il che si traduce in dati diversi da quelli previsti.

fonte


ad esempio, colui che ha creato la transazione è disconnesso dal server, sarà in grado di accedere nuovamente al server per chiudere la transazione?
JanLeeYu,

Quando SQL Server rileva che la connessione è stata persa, verrà ripristinata la transazione. Vedi qui dba.stackexchange.com/questions/47404/… . Se lo stesso utente si riconnette, si tratterà di una sessione diversa, quindi non può in qualche modo "adottare" la vecchia transazione.
Michael Green,
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.