Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak niejawne transakcje działają w SQL Server

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 jak SELECT GETDATE() lub SELECT 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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Praktyczny wybór procesorów dla obciążeń SQL Server 2014/2016 OLTP

  2. CONVERT() vs TRY_CONVERT w SQL Server:jaka jest różnica?

  3. Jak zwrócić podciąg z ciągu w SQL Server za pomocą funkcji SUBSTRING()?

  4. Używanie warunku if we wstawianiu SQL Server

  5. Jak mogę przekonwertować Sql Server 2008 DateTimeOffset na DateTime?