Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como as transações implícitas funcionam no SQL Server


Existem quatro modos de transação no SQL Server. Um deles é o modo implícito.

No SQL Server, uma transação implícita é quando uma nova transação é iniciada implicitamente quando a transação anterior é concluída, mas cada transação é explicitamente concluída com um COMMIT ou ROLLBACK demonstração.

Isso não deve ser confundido com o modo de confirmação automática, onde a transação é iniciada e encerrada implicitamente.

Os quatro modos de transação


O SQL Server pode operar nos seguintes modos de transação:
Modo de transação Descrição
Transação de confirmação automática Cada extrato individual é uma transação.
Transação implícita Uma nova transação é iniciada implicitamente quando a transação anterior é concluída, mas cada transação é explicitamente concluída, normalmente com um COMMIT ou ROLLBACK declaração dependendo do DBMS.
Transação explícita Iniciado explicitamente com uma linha como START TRANSACTION , BEGIN TRANSACTION ou similar, dependendo do DBMS, e explicitamente confirmado ou revertido com as instruções relevantes.
Transação com escopo de lote Aplicável apenas a vários conjuntos de resultados ativos (MARS). Uma transação explícita ou implícita que começa em uma sessão MARS se torna uma transação com escopo de lote.

Modo implícito x confirmação automática


No SQL Server, determinadas instruções iniciam uma transação automaticamente quando são executadas. É como se eles fossem precedidos por um BEGIN TRANSACTION invisível demonstração.

Na maioria dos casos, essas transações também são confirmadas implicitamente, como se houvesse um COMMIT TRANSACTION invisível demonstração. Diz-se que essas transações estão no modo de confirmação automática .

Em outros casos, não há COMMIT TRANSACTION invisível para corresponder ao invisível BEGIN TRANSACTION demonstração. A transação permanece em andamento até que você a confirme explicitamente ou a reverta com um COMMIT TRANSACTION ou ROLLBACK TRANSACTION demonstração. Nesse caso, diz-se que a transação está no modo implícito .

Se a transação é executada no modo implícito ou no modo de confirmação automática, depende do seu IMPLICIT_TRANSACTIONS contexto.

Declarações que iniciam uma transação implícita


As instruções a seguir iniciam uma transação implícita no SQL Server.
  • ALTER TABLE
  • BEGIN TRANSACTION
  • CREATE
  • DELETE
  • DROP
  • FETCH
  • GRANT
  • INSERT
  • OPEN
  • REVOKE
  • SELECT (exceto aqueles que não selecionam de uma tabela, como SELECT GETDATE() ou SELECT 1*1 )
  • TRUNCATE TABLE
  • UPDATE

Sempre que você executa essas instruções T-SQL, está iniciando uma transação. Na maioria das vezes, a transação será confirmada automaticamente. Então você iniciou e finalizou a transação sem precisar fazer isso explicitamente.

No entanto, dependendo do seu IMPLICIT_TRANSACTIONS configuração, pode ser necessário confirmar a transação explicitamente.

Quando IMPLICIT_TRANSACTIONS está OFF


Quando seu IMPLICIT_TRANSACTIONS configuração é OFF , as instruções acima realizam transações no modo de confirmação automática. Ou seja, eles começam e encerrar a transação implicitamente.

É como ter um BEGIN TRANSACTION invisível instrução e um invisível COMMIT TRANSACTION declaração, tudo a partir de uma declaração.

Nesse caso, você não precisa fazer nada para confirmar ou reverter a transação. Já foi feito para você.

Quando IMPLICIT_TRANSACTIONS está ON


Quando seu IMPLICIT_TRANSACTIONS configuração está ON , as instruções acima se comportam um pouco diferente.

Quando IMPLICIT_TRANSACTIONS configuração está ON , as instruções acima recebem um BEGIN TRANSACTION invisível mas não recebem um COMMIT TRANSACTION correspondente demonstração.

Isso significa que você mesmo precisa confirmar ou reverter a transação explicitamente.

No entanto, quando o modo de transação está implícito, nenhum BEGIN TRANSACTION invisível é emitido se uma transação já estiver em andamento.

Exemplo


Aqui está um exemplo para demonstrar o conceito.
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)

Nesse caso, defino IMPLICIT_TRANSACTIONS para OFF e execute o SELECT demonstração. Isso significava que o SELECT A instrução foi executada no modo de confirmação automática e, portanto, a transação foi iniciada e encerrada implicitamente.

@@TRANCOUNT retornou 0 , o que significa que não havia transações em execução naquele momento.

Aqui está novamente, exceto que desta vez definimos IMPLICIT_TRANSACTIONS para 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)

O último @@TRANCOUNT está retornando um valor de 1 . Isso significa que nossa transação ainda está em andamento.

@@TRANCOUNT retorna o número de BEGIN TRANSACTION instruções que ocorreram na conexão atual. Não emitimos um explicitamente, mas um foi emitido implicitamente.

Então, na verdade, precisamos confirmar essa transação (ou revertê-la) para diminuir o @@TRANCOUNT até 0 .
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;

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

Portanto, o código para nossa transação implícita deve incluir o COMMIT demonstração:
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


Se você achar que as transações implícitas estão habilitadas inesperadamente, pode ser por causa do ANSI_DEFAULTS contexto.