sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo funcionan las transacciones implícitas en SQL Server

Hay cuatro modos de transacción en SQL Server. Uno de estos es el modo implícito.

En SQL Server, una transacción implícita es cuando se inicia implícitamente una nueva transacción cuando se completa la transacción anterior, pero cada transacción se completa explícitamente con un COMMIT o ROLLBACK declaración.

Esto no debe confundirse con el modo de confirmación automática, donde la transacción se inicia y finaliza implícitamente.

Los cuatro modos de transacción

SQL Server puede operar en los siguientes modos de transacción:

Modo de transacción Descripción
Transacción de confirmación automática Cada declaración individual es una transacción.
Transacción implícita Una nueva transacción se inicia implícitamente cuando se completa la transacción anterior, pero cada transacción se completa explícitamente, normalmente con un COMMIT o ROLLBACK declaración dependiendo del DBMS.
Transacción explícita Comenzó explícitamente con una línea como START TRANSACTION , BEGIN TRANSACTION o similar, según el DBMS, y confirmado o revertido explícitamente con las declaraciones relevantes.
Transacción por lotes Aplicable solo a múltiples conjuntos de resultados activos (MARS). Una transacción explícita o implícita que se inicia en una sesión de MARS se convierte en una transacción por lotes.

Modo implícito frente a confirmación automática

En SQL Server, ciertas declaraciones inician una transacción automáticamente cuando se ejecutan. Es como si estuvieran precedidos por un BEGIN TRANSACTION invisible declaración.

En la mayoría de los casos, estas transacciones también se confirman implícitamente, como si hubiera una COMMIT TRANSACTION invisible. declaración. Se dice que tales transacciones están en modo de confirmación automática .

En otros casos, no hay COMMIT TRANSACTION invisible para que coincida con el invisible BEGIN TRANSACTION declaración. La transacción permanece en progreso hasta que la confirme explícitamente o la revierta con un COMMIT TRANSACTION o ROLLBACK TRANSACTION declaración. En este caso, se dice que la transacción está en modo implícito .

Si la transacción se ejecuta en modo implícito o en modo de confirmación automática depende de sus IMPLICIT_TRANSACTIONS ajuste.

Declaraciones que inician una transacción implícita

Las siguientes declaraciones inician una transacción implícita en SQL Server.

  • ALTER TABLE
  • BEGIN TRANSACTION
  • CREATE
  • DELETE
  • DROP
  • FETCH
  • GRANT
  • INSERT
  • OPEN
  • REVOKE
  • SELECT (excepto aquellos que no seleccionan de una tabla, como SELECT GETDATE() o SELECT 1*1 )
  • TRUNCATE TABLE
  • UPDATE

Cada vez que ejecuta estas declaraciones T-SQL, está iniciando una transacción. La mayoría de las veces la transacción se confirmará automáticamente. Entonces comenzó y finalizó la transacción sin tener que hacerlo explícitamente.

Sin embargo, dependiendo de sus IMPLICIT_TRANSACTIONS configuración, es posible que deba confirmar la transacción explícitamente.

Cuando IMPLICIT_TRANSACTIONS está OFF

Cuando su IMPLICIT_TRANSACTIONS la configuración es OFF , las declaraciones anteriores realizan transacciones en modo de confirmación automática. Es decir, comienzan y terminar la transacción implícitamente.

Es como tener una BEGIN TRANSACTION invisible instrucción y un COMMIT TRANSACTION invisible declaración, todo de una declaración.

En este caso, no necesita hacer nada para confirmar o deshacer la transacción. Ya se ha hecho por ti.

Cuando IMPLICIT_TRANSACTIONS está ON

Cuando su IMPLICIT_TRANSACTIONS la configuración es ON , las declaraciones anteriores se comportan de forma ligeramente diferente.

Cuando IMPLICIT_TRANSACTIONS la configuración es ON , las declaraciones anteriores obtienen un BEGIN TRANSACTION invisible pero no obtienen una COMMIT TRANSACTION correspondiente declaración.

Esto significa que usted mismo debe confirmar o deshacer explícitamente la transacción.

Sin embargo, cuando el modo de transacción es implícito, ningún BEGIN TRANSACTION invisible se emite si una transacción ya está en curso.

Ejemplo

Aquí hay un ejemplo para demostrar el concepto.

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

Resultado:

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

En este caso, establecí IMPLICIT_TRANSACTIONS a OFF y ejecuta SELECT declaración. Esto significaba que SELECT La declaración se ejecutó en modo de confirmación automática y, por lo tanto, la transacción se inició y finalizó implícitamente.

@@TRANCOUNT devolvió 0 , lo que significa que no había transacciones ejecutándose en ese momento.

Aquí está de nuevo, excepto que esta vez configuramos IMPLICIT_TRANSACTIONS a ON .

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

Resultado:

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

El último @@TRANCOUNT está devolviendo un valor de 1 . Esto significa que nuestra transacción aún está en progreso.

@@TRANCOUNT devuelve el número de BEGIN TRANSACTION declaraciones que han ocurrido en la conexión actual. No emitimos uno explícitamente, pero uno se emitió implícitamente.

Entonces, en realidad necesitamos confirmar esta transacción (o revertirla) para disminuir el @@TRANCOUNT hasta 0 .

COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;

Resultado:

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

Entonces, el código para nuestra transacción implícita debería haber incluido el COMMIT declaración:

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

Resultado:

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

Si encuentra que las transacciones implícitas se habilitan inesperadamente, podría deberse a ANSI_DEFAULTS entorno.