W SQL Server istnieją cztery tryby transakcji. Jednym z nich jest tryb niejawny.
W SQL Server transakcja niejawna ma miejsce, gdy nowa transakcja jest niejawnie uruchamiana po zakończeniu poprzedniej transakcji, ale każda transakcja jest jawnie zakończona za pomocą COMMIT
lub ROLLBACK
oświadczenie.
Nie należy tego mylić z trybem automatycznego zatwierdzania, w którym transakcja jest rozpoczynana i kończona niejawnie.
Cztery tryby transakcji
SQL Server może działać w następujących trybach transakcji:
Tryb transakcji | Opis |
---|---|
Automatycznie zatwierdzaj transakcję | Każdy indywidualny wyciąg jest transakcją. |
Transakcja niejawna | Nowa transakcja jest niejawnie uruchamiana po zakończeniu poprzedniej transakcji, ale każda transakcja jest jawnie zakończona, zwykle z COMMIT lub ROLLBACK oświadczenie w zależności od DBMS. |
Jawna transakcja | Rozpoczęty wyraźnie od linii, takiej jak START TRANSACTION , START TRANSACTION lub podobne, w zależności od DBMS i jawnie zatwierdzone lub wycofane z odpowiednimi instrukcjami. |
Transakcja o zakresie wsadowym | Dotyczy tylko wielu aktywnych zestawów wyników (MARS). Transakcja jawna lub niejawna, która rozpoczyna się w ramach sesji MARS, staje się transakcją o zakresie wsadowym. |
Tryb niejawny a automatyczne zatwierdzanie
W SQL Server niektóre instrukcje uruchamiają transakcję automatycznie po ich uruchomieniu. To tak, jakby były poprzedzone niewidzialną BEGIN TRANSACTION
oświadczenie.
W większości przypadków te transakcje są również niejawnie zatwierdzane, tak jakby istniała niewidoczna COMMIT TRANSACTION
oświadczenie. Mówi się, że takie transakcje są w trybie automatycznego zatwierdzania .
W innych przypadkach nie ma niewidocznej COMMIT TRANSACTION
aby dopasować niewidoczną BEGIN TRANSACTION
oświadczenie. Transakcja pozostaje w toku, dopóki jej nie zatwierdzisz lub nie wycofasz jej za pomocą COMMIT TRANSACTION
lub ROLLBACK TRANSACTION
oświadczenie. W tym przypadku mówi się, że transakcja jest w trybie niejawnym .
To, czy transakcja zostanie uruchomiona w trybie niejawnym, czy w trybie automatycznego zatwierdzania, zależy od Twoich IMPLICIT_TRANSACTIONS
ustawienie.
Oświadczenia, które rozpoczynają niejawną transakcję
Poniższe instrukcje rozpoczynają niejawną transakcję w SQL Server.
ALTER TABLE
START TRANSACTION
CREATE
DELETE
DROP
FETCH
GRANT
INSERT
OPEN
REVOKE
SELECT
(z wyjątkiem tych, które nie wybierają z tabeli, takich jakSELECT GETDATE()
lubSELECT 1*1
)TRUNCATE TABLE
UPDATE
Za każdym razem, gdy uruchamiasz te instrukcje T-SQL, rozpoczynasz transakcję. W większości przypadków transakcja zostanie zatwierdzona automatycznie. Rozpocząłeś i zakończyłeś transakcję bez konieczności wyraźnego robienia tego.
Jednak w zależności od Twoich IMPLICIT_TRANSACTIONS
ustawienie, może być konieczne wyraźne zatwierdzenie transakcji.
Kiedy IMPLICIT_TRANSACTIONS
jest OFF
Gdy Twoje IMPLICIT_TRANSACTIONS
ustawienie jest OFF
, powyższe oświadczenia wykonują transakcje w trybie autocommit. Oznacza to, że zaczynają i zakończyć transakcję domyślnie.
To tak, jakby mieć niewidzialną BEGIN TRANSACTION
oświadczenie i niewidoczny COMMIT TRANSACTION
oświadczenie, wszystko z jednego oświadczenia.
W takim przypadku nie musisz nic robić, aby zatwierdzić lub wycofać transakcję. To już zostało dla Ciebie zrobione.
Kiedy IMPLICIT_TRANSACTIONS
jest ON
Gdy Twoje IMPLICIT_TRANSACTIONS
ustawienie jest ON
, powyższe stwierdzenia zachowują się nieco inaczej.
Kiedy IMPLICIT_TRANSACTIONS
ustawienie jest ON
, powyższe instrukcje uzyskują niewidoczną BEGIN TRANSACTION
oświadczenie, ale nie otrzymują odpowiedniego COMMIT TRANSACTION
oświadczenie.
Oznacza to, że musisz samodzielnie zatwierdzić lub wycofać transakcję.
Jednak gdy tryb transakcji jest niejawny, niewidoczne BEGIN TRANSACTION
jest emitowany, jeśli transakcja jest już w toku.
Przykład
Oto przykład demonstrujący tę koncepcję.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS OFF;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Wynik:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
W tym przypadku ustawiam IMPLICIT_TRANSACTIONS
na OFF
i uruchom SELECT
oświadczenie. Oznaczało to, że SELECT
instrukcja została uruchomiona w trybie automatycznego zatwierdzania, a zatem transakcja została rozpoczęta i zakończona niejawnie.
@@TRANCOUNT
zwrócono 0
, co oznacza, że w tym momencie nie było żadnych transakcji.
Oto znowu, z tym wyjątkiem, że tym razem ustawiamy IMPLICIT_TRANSACTIONS
na ON
.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Wynik:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 1 | +--------------------+ (1 row affected)
Ostatni @@TRANCOUNT
zwraca wartość 1
. Oznacza to, że nasza transakcja wciąż trwa.
@@TRANCOUNT
zwraca liczbę BEGIN TRANSACTION
oświadczenia, które wystąpiły w bieżącym połączeniu. Nie wydaliśmy go wprost, ale jeden został wydany w sposób dorozumiany.
Tak więc faktycznie musimy zatwierdzić tę transakcję (lub wycofać ją) w celu zmniejszenia @@TRANCOUNT
aż do 0
.
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Wynik:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
Tak więc kod naszej niejawnej transakcji powinien zawierać COMMIT
oświadczenie:
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Wynik:
+--------------------+ | 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
Jeśli okaże się, że transakcje niejawne są włączane nieoczekiwanie, może to być spowodowane ANSI_DEFAULTS
ustawienie.