Esistono quattro modalità di transazione in SQL Server. Uno di questi è la modalità implicita.
In SQL Server, una transazione implicita è quando una nuova transazione viene avviata implicitamente al completamento della transazione precedente, ma ogni transazione viene completata in modo esplicito con un COMMIT
o ROLLBACK
dichiarazione.
Questo non deve essere confuso con la modalità autocommit, in cui la transazione viene avviata e terminata in modo implicito.
Le quattro modalità di transazione
SQL Server può funzionare nelle seguenti modalità di transazione:
Modalità transazione | Descrizione |
---|---|
Autocommit transazione | Ogni singolo estratto conto è una transazione. |
Transazione implicita | Una nuova transazione viene avviata implicitamente al completamento della transazione precedente, ma ogni transazione viene completata in modo esplicito, in genere con un COMMIT o ROLLBACK istruzione a seconda del DBMS. |
Transazione esplicita | Iniziato esplicitamente con una riga come START TRANSACTION , BEGIN TRANSACTION o simili, a seconda del DBMS, e esplicitamente impegnati o annullati con le dichiarazioni pertinenti. |
Transazione con ambito batch | Applicabile solo a più set di risultati attivi (MARS). Una transazione esplicita o implicita che inizia in una sessione MARS diventa una transazione con ambito batch. |
Modalità implicita vs Autocommit
In SQL Server, alcune istruzioni avviano automaticamente una transazione quando vengono eseguite. È come se fossero preceduti da un invisibile BEGIN TRANSACTION
dichiarazione.
Nella maggior parte dei casi, queste transazioni sono anche impegnate in modo implicito, come se ci fosse una COMMIT TRANSACTION
invisibile dichiarazione. Si dice che tali transazioni siano in modalità di commit automatico .
Negli altri casi, non c'è COMMIT TRANSACTION
invisibile per abbinare l'invisibile BEGIN TRANSACTION
dichiarazione. La transazione rimane in corso fino a quando non la commetti in modo esplicito o la annulli con un COMMIT TRANSACTION
o ROLLBACK TRANSACTION
dichiarazione. In questo caso, si dice che la transazione è in modalità implicita .
Se la transazione viene eseguita in modalità implicita o in modalità autocommit dipende dal tuo IMPLICIT_TRANSACTIONS
impostazione.
Dichiarazioni che avviano una transazione implicita
Le istruzioni seguenti avviano una transazione implicita in SQL Server.
ALTER TABLE
BEGIN TRANSACTION
CREATE
DELETE
DROP
FETCH
GRANT
INSERT
OPEN
REVOKE
SELECT
(tranne quelli che non selezionano da una tabella, comeSELECT GETDATE()
oSELECT 1*1
)TRUNCATE TABLE
UPDATE
Ogni volta che esegui queste istruzioni T-SQL, stai avviando una transazione. La maggior parte delle volte la transazione verrà automaticamente impegnata. Quindi hai iniziato e terminato la transazione senza doverlo fare esplicitamente.
Tuttavia, a seconda del tuo IMPLICIT_TRANSACTIONS
impostazione, potrebbe essere necessario confermare la transazione in modo esplicito.
Quando IMPLICIT_TRANSACTIONS
è OFF
Quando il tuo IMPLICIT_TRANSACTIONS
l'impostazione è OFF
, le istruzioni di cui sopra eseguono transazioni in modalità autocommit. Cioè, iniziano e terminare la transazione in modo implicito.
Quindi è come avere un BEGIN TRANSACTION
invisibile istruzione e un invisibile COMMIT TRANSACTION
dichiarazione, tutto da un'unica dichiarazione.
In questo caso, non è necessario eseguire alcuna operazione per eseguire il commit o il rollback della transazione. Per te è già stato fatto.
Quando IMPLICIT_TRANSACTIONS
è ON
Quando il tuo IMPLICIT_TRANSACTIONS
l'impostazione è ON
, le affermazioni di cui sopra si comportano in modo leggermente diverso.
Quando IMPLICIT_TRANSACTIONS
l'impostazione è ON
, le istruzioni di cui sopra ottengono un BEGIN TRANSACTION
invisibile ma non ottengono una COMMIT TRANSACTION
corrispondente dichiarazione.
Ciò significa che è necessario eseguire personalmente il commit o il rollback della transazione.
Tuttavia, quando la modalità di transazione è implicita, nessun BEGIN TRANSACTION
invisibile viene emesso se una transazione è già in corso.
Esempio
Ecco un esempio per dimostrare il concetto.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS OFF;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Risultato:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
In questo caso, ho impostato IMPLICIT_TRANSACTIONS
su OFF
ed esegui SELECT
dichiarazione. Ciò significava che il SELECT
l'istruzione è stata eseguita in modalità autocommit e, pertanto, la transazione è stata avviata e terminata in modo implicito.
@@TRANCOUNT
restituito 0
, il che significa che non c'erano transazioni in esecuzione in quel momento.
Eccolo di nuovo, tranne che questa volta impostiamo IMPLICIT_TRANSACTIONS
su ON
.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Risultato:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 1 | +--------------------+ (1 row affected)
L'ultimo @@TRANCOUNT
restituisce un valore di 1
. Ciò significa che la nostra transazione è ancora in corso.
@@TRANCOUNT
restituisce il numero di BEGIN TRANSACTION
dichiarazioni che si sono verificate sulla connessione corrente. Non ne abbiamo emesso uno esplicitamente, ma uno è stato emesso implicitamente.
Quindi abbiamo effettivamente bisogno di eseguire questa transazione (o annullarla) per decrementare il @@TRANCOUNT
fino a 0
.
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Risultato:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
Quindi il codice per la nostra transazione implicita avrebbe dovuto includere COMMIT
dichiarazione:
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Risultato:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) Commands completed successfully. +--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
ANSI_DEFAULTS
Se scopri che le transazioni implicite sono abilitate in modo imprevisto, potrebbe essere a causa di ANSI_DEFAULTS
collocamento.