Det finns fyra transaktionslägen i SQL Server. En av dessa är implicit läge.
I SQL Server är en implicit transaktion när en ny transaktion implicit startas när den föregående transaktionen slutförs, men varje transaktion är explicit slutförd med en COMMIT
eller ROLLBACK
uttalande.
Detta ska inte förväxlas med autocommit-läge, där transaktionen startas och avslutas implicit.
De fyra transaktionslägena
SQL Server kan fungera i följande transaktionslägen:
Transaktionsläge | Beskrivning |
---|---|
Autocommit transaktion | Varje individuellt uttalande är en transaktion. |
Implicit transaktion | En ny transaktion startas implicit när den föregående transaktionen slutförs, men varje transaktion är explicit slutförd, vanligtvis med en COMMIT eller ROLLBACK uttalande beroende på DBMS. |
Explicit transaktion | Började explicit med en rad som START TRANSACTION , BEGIN TRANSACTION eller liknande, beroende på DBMS, och uttryckligen åtagit sig eller rullat tillbaka med relevanta uttalanden. |
Batch-omfattad transaktion | Gäller endast för flera aktiva resultatuppsättningar (MARS). En explicit eller implicit transaktion som startar under en MARS-session blir en batch-omfattad transaktion. |
Implicit läge vs Autocommit
I SQL Server startar vissa satser en transaktion automatiskt när de körs. Det är som om de föregåtts av en osynlig BEGIN TRANSACTION
uttalande.
I de flesta fall är dessa transaktioner också implicit utförda, som om det fanns en osynlig COMMIT TRANSACTION
påstående. Sådana transaktioner sägs vara i autocommit-läge .
I andra fall finns det ingen osynlig COMMIT TRANSACTION
för att matcha den osynliga BEGIN TRANSACTION
påstående. Transaktionen förblir pågående tills du uttryckligen genomför den eller återställer den med en COMMIT TRANSACTION
eller ROLLBACK TRANSACTION
påstående. I det här fallet sägs transaktionen vara i implicit läge .
Huruvida transaktionen körs i implicit läge eller autocommit-läge beror på din IMPLICIT_TRANSACTIONS
inställning.
Uttalanden som startar en implicit transaktion
Följande satser startar en implicit transaktion i SQL Server.
ALTER TABLE
BEGIN TRANSACTION
CREATE
DELETE
DROP
FETCH
GRANT
INSERT
OPEN
REVOKE
SELECT
(förutom de som inte väljer från en tabell, till exempelSELECT GETDATE()
ellerSELECT 1*1
)TRUNCATE TABLE
UPDATE
Varje gång du kör dessa T-SQL-satser startar du en transaktion. För det mesta kommer transaktionen att genomföras automatiskt. Så du startade och avslutade transaktionen utan att uttryckligen behöva göra det.
Men beroende på din IMPLICIT_TRANSACTIONS
kan du behöva utföra transaktionen uttryckligen.
När IMPLICIT_TRANSACTIONS
är OFF
När din IMPLICIT_TRANSACTIONS
inställningen är OFF
, utför ovanstående uttalanden transaktioner i autocommit-läge. Det vill säga, de startar och avsluta transaktionen implicit.
Så det är som att ha en osynlig BEGIN TRANSACTION
uttalande och en osynlig COMMIT TRANSACTION
påstående, allt från ett påstående.
I det här fallet behöver du inte göra något för att begå eller återställa transaktionen. Det var redan gjort för dig.
När IMPLICIT_TRANSACTIONS
är ON
När din IMPLICIT_TRANSACTIONS
inställningen är ON
, ovanstående påståenden beter sig något annorlunda.
När IMPLICIT_TRANSACTIONS
inställningen är ON
, ovanstående påståenden får en osynlig BEGIN TRANSACTION
men de får inte en motsvarande COMMIT TRANSACTION
uttalande.
Detta innebär att du uttryckligen måste utföra eller återställa transaktionen själv.
Men när transaktionsläget är implicit, ingen osynlig BEGIN TRANSACTION
utfärdas om en transaktion redan pågår.
Exempel
Här är ett exempel för att demonstrera konceptet.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS OFF;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Resultat:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
I det här fallet ställer jag in IMPLICIT_TRANSACTIONS
till OFF
och kör SELECT
påstående. Detta innebar att SELECT
uttalandet körde i autocommit-läge, och därför startades och avslutades transaktionen implicit.
@@TRANCOUNT
returnerade 0
, vilket betyder att det inte fanns några transaktioner som kördes vid den tidpunkten.
Här är det igen, förutom att den här gången ställer vi in IMPLICIT_TRANSACTIONS
till ON
.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Resultat:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 1 | +--------------------+ (1 row affected)
Den sista @@TRANCOUNT
returnerar värdet 1
. Det betyder att vår transaktion fortfarande pågår.
@@TRANCOUNT
returnerar antalet BEGIN TRANSACTION
uttalanden som har inträffat på den aktuella anslutningen. Vi utfärdade inte uttryckligen en, men en utfärdades implicit.
Så vi måste faktiskt utföra den här transaktionen (eller återställa den) för att minska @@TRANCOUNT
ner till 0
.
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Resultat:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
Så koden för vår implicita transaktion borde ha inkluderat COMMIT
uttalande:
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Resultat:
+--------------------+ | 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
Om du upptäcker att implicita transaktioner oväntat aktiveras kan det bero på ANSI_DEFAULTS
miljö.