sql >> Database >  >> RDS >> Sqlserver

Hoe impliciete transacties werken in SQL Server

Er zijn vier transactiemodi in SQL Server. Een daarvan is de impliciete modus.

In SQL Server is een impliciete transactie wanneer een nieuwe transactie impliciet wordt gestart wanneer de eerdere transactie is voltooid, maar elke transactie wordt expliciet voltooid met een COMMIT of ROLLBACK verklaring.

Dit moet niet worden verward met de autocommit-modus, waarbij de transactie impliciet wordt gestart en beëindigd.

De vier transactiemodi

SQL Server kan in de volgende transactiemodi werken:

Transactiemodus Beschrijving
Transactie automatisch vastleggen Elk individueel overzicht is een transactie.
Impliciete transactie Een nieuwe transactie wordt impliciet gestart wanneer de vorige transactie is voltooid, maar elke transactie wordt expliciet voltooid, meestal met een COMMIT of ROLLBACK statement afhankelijk van het DBMS.
Expliciete transactie Expliciet begonnen met een regel zoals START TRANSACTION , BEGIN TRANSACTION of vergelijkbaar, afhankelijk van het DBMS, en expliciet vastgelegd of teruggedraaid met de relevante instructies.
Batch-scoped transactie Alleen van toepassing op meerdere actieve resultatensets (MARS). Een expliciete of impliciete transactie die begint onder een MARS-sessie, wordt een transactie met batchbereik.

Impliciete modus vs Autocommit

In SQL Server starten bepaalde instructies automatisch een transactie wanneer ze worden uitgevoerd. Het is alsof ze worden voorafgegaan door een onzichtbare BEGIN TRANSACTION verklaring.

In de meeste gevallen worden deze transacties ook impliciet vastgelegd, alsof er een onzichtbare COMMIT TRANSACTION is. uitspraak. Van dergelijke transacties wordt gezegd dat ze zich in de autocommit-modus bevinden .

In andere gevallen is er geen onzichtbare COMMIT TRANSACTION om overeen te komen met de onzichtbare BEGIN TRANSACTION uitspraak. De transactie blijft in uitvoering totdat u deze expliciet vastlegt of terugdraait met een COMMIT TRANSACTION of ROLLBACK TRANSACTION uitspraak. In dit geval staat de transactie in de impliciete modus .

Of de transactie in de impliciete modus of in de autocommit-modus wordt uitgevoerd, hangt af van uw IMPLICIT_TRANSACTIONS instelling.

Afschriften die een impliciete transactie starten

De volgende instructies starten een impliciete transactie in SQL Server.

  • ALTER TABLE
  • BEGIN TRANSACTION
  • CREATE
  • DELETE
  • DROP
  • FETCH
  • GRANT
  • INSERT
  • OPEN
  • REVOKE
  • SELECT (behalve degenen die niet uit een tabel selecteren, zoals SELECT GETDATE() of SELECT 1*1 )
  • TRUNCATE TABLE
  • UPDATE

Elke keer dat u deze T-SQL-instructies uitvoert, start u een transactie. Meestal wordt de transactie automatisch vastgelegd. U bent dus de transactie gestart en beëindigd zonder dat u dit expliciet hoeft te doen.

Afhankelijk van uw IMPLICIT_TRANSACTIONS instelling, moet u de transactie mogelijk expliciet vastleggen.

Wanneer IMPLICIT_TRANSACTIONS is OFF

Wanneer uw IMPLICIT_TRANSACTIONS instelling is OFF , voeren de bovenstaande instructies transacties uit in de autocommit-modus. Dat wil zeggen, ze beginnen en de transactie impliciet beëindigen.

Het is dus alsof je een onzichtbare BEGIN TRANSACTION . hebt statement en een onzichtbare COMMIT TRANSACTION verklaring, allemaal van de ene verklaring.

In dit geval hoeft u niets te doen om de transactie vast te leggen of terug te draaien. Het is al voor je gedaan.

Wanneer IMPLICIT_TRANSACTIONS is ON

Wanneer uw IMPLICIT_TRANSACTIONS instelling is ON , gedragen de bovenstaande uitspraken zich iets anders.

Wanneer IMPLICIT_TRANSACTIONS instelling is ON , krijgen de bovenstaande instructies een onzichtbare BEGIN TRANSACTION statement, maar ze krijgen geen overeenkomstige COMMIT TRANSACTION verklaring.

Dit betekent dat u de transactie expliciet zelf moet vastleggen of terugdraaien.

Wanneer de transactiemodus echter impliciet is, is er geen onzichtbare BEGIN TRANSACTION wordt uitgegeven als er al een transactie aan de gang is.

Voorbeeld

Hier is een voorbeeld om het concept te demonstreren.

SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS OFF;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;

Resultaat:

+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)
Commands completed successfully.
+-------------------------+----------------+
| ProductName             | ProductPrice   |
|-------------------------+----------------|
| Left handed screwdriver | 25.99          |
+-------------------------+----------------+
(1 row affected)
+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)

In dit geval stel ik IMPLICIT_TRANSACTIONS . in naar OFF en voer de SELECT uitspraak. Dit betekende dat de SELECT statement liep in de autocommit-modus en daarom werd de transactie impliciet gestart en beëindigd.

@@TRANCOUNT geretourneerde 0 , wat betekent dat er op dat moment geen transacties liepen.

Hier is het weer, maar deze keer hebben we IMPLICIT_TRANSACTIONS ingesteld naar ON .

SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;

Resultaat:

+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)
Commands completed successfully.
+-------------------------+----------------+
| ProductName             | ProductPrice   |
|-------------------------+----------------|
| Left handed screwdriver | 25.99          |
+-------------------------+----------------+
(1 row affected)
+--------------------+
| TransactionCount   |
|--------------------|
| 1                  |
+--------------------+
(1 row affected)

De laatste @@TRANCOUNT retourneert een waarde van 1 . Dit betekent dat onze transactie nog in uitvoering is.

@@TRANCOUNT geeft het aantal BEGIN TRANSACTION . terug verklaringen die zijn opgetreden op de huidige verbinding. We hebben er niet expliciet een uitgegeven, maar er is er wel een impliciet uitgegeven.

We moeten deze transactie dus daadwerkelijk vastleggen (of terugdraaien) om de @@TRANCOUNT te verlagen tot 0 .

COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;

Resultaat:

+--------------------+
| TransactionCount   |
|--------------------|
| 0                  |
+--------------------+
(1 row affected)

Dus de code voor onze impliciete transactie had de COMMIT . moeten bevatten verklaring:

SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;

Resultaat:

+--------------------+
| 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

Als u merkt dat impliciete transacties onverwacht worden ingeschakeld, kan dit komen door de ANSI_DEFAULTS instelling.


  1. SQL vervangt alle NULL's

  2. Databaseservices op AWS en Oracle Cloud Platform

  3. Schending van UNIQUE KEY-beperking op INSERT WHERE COUNT(*) =0 op SQL Server 2005

  4. PHP laadt php_pgsql.dll niet op Windows