Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Utilizzo di Transaction ROLLBACK in SQL Server

Introduzione

Molto recentemente, un mio collega è venuto da me in preda alla disperazione ammettendo di aver rilasciato una dichiarazione di aggiornamento senza una clausola WHERE su una tabella di applicazione chiave. Le implicazioni sul front-end sarebbero terribili, quindi è venuto da me direttamente perché aveva urgente bisogno di aiuto per invertire la situazione con qualsiasi mezzo prima che le email e l'escalation iniziassero a riversarsi.

Quando abbiamo esaminato la situazione, abbiamo scoperto che le modifiche non sono state applicate nel database secondario. Nella maggior parte dei casi, il ritardo tra i nostri database primari e secondari è di venti minuti (abbiamo un po' sbalorditivo per evitare problemi di prestazioni). Poiché il mio collega ha chiesto aiuto subito dopo aver realizzato l'errore, siamo stati in grado di recuperare i dati dal database secondario. Ho descritto il valore di tale ritardo in questo articolo .

Revisione dello scenario

Lo scenario che ho descritto sopra non è raro. Uno dei motivi per cui ciò accade agli utenti regolari di SQL Server è che SQL Server utilizza quelle che vengono chiamate Transazioni implicite. Le transazioni implicite sono disattivate per impostazione predefinita, il che significa che SQL Server non prevede l'emissione di un'istruzione COMMIT TRANSACTION alla fine di ogni istruzione. In effetti, ogni istruzione viene confermata automaticamente. Questo è conveniente e aiuta a evitare situazioni in cui le sessioni che devono ancora essere impegnate finiscono per bloccare le risorse e influire sulle prestazioni. Brent Ozar fornisce maggiori dettagli sulle implicazioni sul rendimento di TRANSAZIONI IMPLICITE =ON.

Tuttavia, un piccolo aspetto negativo di questa configurazione (TRASAZIONI IMPLICITE =OFF) è che gli utenti non hanno l'opportunità di ripensare a una dichiarazione ed emettere un ROLLBACK che è molto comune in Oracle. La Fig. 1 mostra le opzioni di query ANSI disponibili in SQL Server Management Studio.

Fig. 1 ANSI predefinito in SQL Server Management Studio

Utilizzo di transazioni implicite

In sostanza, il problema che dobbiamo affrontare in questa configurazione predefinita o nel nostro strumento client più desiderabile è che non possiamo eseguire il ROLLBACK una volta eseguita un'istruzione SQL. Possiamo aggirare questo problema abilitando TRANSAZIONI IMPLICITE nella nostra sessione. Questo ci darà l'opportunità di eseguire il ROLLBACK delle transazioni se necessario. Fig. 2 e Fig. 4 ci mostrano che possiamo avere questa impostazione attivata solo per una sessione, anche se questo non elimina il rischio che la sessione utente ne blocchi altre se non viene emesso un ROLLBACK o un COMMIT.

Fig. 2 TRANSAZIONI IMPLICITE IN UN'UNICA SEDUTA

-- Listing 1: UPDATE Table TAB2 with IMPLICIT_TRANSACTIONS ON
SET IMPLICIT_TRANSACTIONS ON

DECLARE @IMPLICIT_TRANSACTIONS VARCHAR(3) = 'OFF';  
IF ( (2 & @@OPTIONS) = 2 ) SET @IMPLICIT_TRANSACTIONS = 'ON';  
SELECT @IMPLICIT_TRANSACTIONS AS IMPLICIT_TRANSACTIONS;

USE KTrain
GO
SELECT * FROM Tab2;
GO

UPDATE TAB2
SET countryCode='SA'
-- WHERE fname='Joyce';
GO
SELECT * FROM Tab2;
GO

Fig. 3 Tutte le righe aggiornate

Per illustrare la soluzione qui descritta, diamo un'occhiata al codice SQL nel Listato 1. Supponiamo che un normale utente di SQL Server, uno sviluppatore junior, abbia ricevuto una serie di script da eseguire in determinate condizioni . Nello script, la clausola WHERE è stata commentata perché ci si aspetta che ogni volta che eseguono questo script, cambino il predicato. Naturalmente, questo è un caso d'uso semplice e il rischio può essere affrontato in diversi modi, ma vogliamo solo mostrare la possibilità di eseguire un ROLLBACK.

Ricorda che abbiamo già attivato TRANSAZIONE IMPLICITA, quindi quando eseguiamo questa istruzione, SQL Server si aspetta che effettuiamo COMMIT o ROLLBACK della transazione. L'intenzione dello sviluppatore è aggiornare il countryCode di Joyce Afam in "SA" da quando è immigrata in Sud Africa. La Fig. 3 ci mostra che lo sviluppatore, mentre tentava di farlo, ha accidentalmente aggiornato tutte le righe con il valore SA come Codice Paese . Se ne accorgono ed emettono un ROLLBACK.

Fig. 4 Emissione del ROLLBACK

Fig. 5 TRANSAZIONI IMPLICITE attive in un'altra sessione

Tuttavia, nell'altra sessione in cui non abbiamo attivato TRANSAZIONI IMPLICITE, scopriamo che lo sviluppatore non è in grado di recuperare dall'errore. Non possono emettere correttamente un ROLLBACK in questo caso. Il ripristino comporterebbe quindi il ripristino dei dati.

Fig. 6 ROLLBACK impossibile senza TRANSAZIONI IMPLICITE SU

Utilizzo di transazioni esplicite

Un altro approccio per ottenere lo stesso effetto è racchiudere il DML in una transazione dichiarando esplicitamente BEGIN TRAN. Ancora una volta, è molto importante completare la transazione, utilizzando COMMIT o ROLLBACK. Nel contesto di questa discussione, emettiamo un ROLLBACK poiché ci rendiamo conto che c'è un errore nel codice.

-- Listing 2: UPDATE Table TAB2 with Explicit Transaction

BEGIN TRAN 
GO
USE KTrain
GO
SELECT * FROM Tab2;
GO

UPDATE TAB2
SET countryCode='GH'
-- WHERE fname='Joyce';
GO
SELECT * FROM Tab2;
GO

ROLLBACK;

SELECT * FROM Tab2;
GO

- Listing 3: Corrected UPDATE Statement

BEGIN TRAN 
GO
USE KTrain
GO
SELECT * FROM Tab2;
GO

UPDATE TAB2
SET countryCode='SA'
WHERE fname='Joyce';
GO
SELECT * FROM Tab2;
GO

Conclusione

In questo articolo, abbiamo accennato brevemente a una buona soluzione alternativa per creare opportunità di ROLLBACK e quindi mitigare gli errori degli utenti derivanti da DML errato. Abbiamo anche evidenziato un rischio chiave di questo approccio, che è il blocco involontario. Un DBA può avviare indagini sulla possibile presenza di questo rischio interrogando sys.dm_tran_session_transactions, sys.dm_tran_locks e oggetti di gestione dinamica simili.

Riferimenti

  1. Correzione della perdita di dati utilizzando il log shipping con recupero ritardato

  2. Imposta transazioni implicite

  3. Imposta le transazioni implicite come una cattiva idea

  4. DMV per le transazioni