Se você está recebendo o erro Msg 3902, Level 16, que diz "A solicitação COMMIT TRANSACTION não tem BEGIN TRANSACTION correspondente", provavelmente é porque você tem um
COMMIT perdido demonstração. Você pode estar recebendo isso devido à implementação do tratamento de erros e esquecendo que já confirmou ou reverteu a transação em outro lugar do seu código.
Exemplo de erro
Aqui está um exemplo simples para demonstrar o erro:
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION; Resultado:
(7 rows affected) Msg 3902, Level 16, State 1, Line 2 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
Isso ocorrerá se o seu
SET IMPLICIT_TRANSACTIONS está OFF . Veja abaixo o que acontece quando SET IMPLICIT_TRANSACTIONS está ON . Exemplo de erro devido ao tratamento de erros
Você pode estar recebendo isso devido à implementação do tratamento de erros e esquecendo que já confirmou ou reverteu a transação em outro lugar do seu código.
Por exemplo:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
COMMIT TRANSACTION; Resultado:
(1 row affected) (1 row affected) (1 row affected) Msg 3902, Level 16, State 1, Line 20 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
Nesse caso, eu já tinha
COMMIT TRANSACTION no TRY quadra. Então, quando o segundo COMMIT TRANSACTION foi encontrado, a transação já havia sido confirmada. Veríamos o mesmo mesmo que a transação encontrasse um erro e fosse revertida. Uma reversão encerrará a transação e, portanto, não haverá mais
COMMIT declarações são necessárias. Então, para corrigir esse problema, simplesmente removemos o último
COMMIT TRANSACTION , e o código da transação ficaria assim:BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH Transações Implícitas
Se você tiver transações implícitas habilitadas, poderá obter resultados diferentes do primeiro exemplo.
Se definirmos
IMPLICIT_TRANSACTIONS para ON , eis o que obtemos:SET IMPLICIT_TRANSACTIONS ON;
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION; Resultado:
+---------------------------------+----------------+ | ProductName | ProductPrice | |---------------------------------+----------------| | Left handed screwdriver | 25.99 | | Long Weight (blue) | 14.75 | | Long Weight (green) | 11.99 | | Sledge Hammer | 33.49 | | Chainsaw | 245.00 | | Straw Dog Box | 55.99 | | Bottomless Coffee Mugs (4 Pack) | 9.99 | +---------------------------------+----------------+ (7 rows affected)
Nenhum erro ocorre.
Isso ocorre porque certas instruções T-SQL iniciam automaticamente uma transação quando são executadas. É como se eles fossem precedidos por um
BEGIN TRANSACTION invisível demonstração. Quando
IMPLICIT_TRANSACTIONS está OFF , essas instruções são confirmadas automaticamente. É como se eles fossem sucedidos por um invisível COMMIT TRANSACTION demonstração. Nesse cenário, a transação está no modo de confirmação automática. Quando
IMPLICIT_TRANSACTIONS está ON , não há COMMIT TRANSACTION invisível demonstração. Essas instruções ainda são iniciadas por um BEGIN TRANSACTION invisível , mas eles precisam ser encerrados explicitamente. Uma transação implícita permanece em andamento até que seja explicitamente confirmada ou explicitamente revertida.
Portanto, neste exemplo, nosso
COMMIT TRANSACTION perdido foi realmente necessária para encerrar a transação implícita.