「COMMITTRANSACTIONリクエストに対応するBEGINTRANSACTIONがありません」というエラーメッセージ3902、レベル16が表示された場合は、COMMIT
が迷っている可能性があります。 ステートメント。
エラー処理を実装し、コード内の他の場所でトランザクションをすでにコミットまたはロールバックしていることを忘れているために、これが発生している可能性があります。
エラーの例
エラーを示す簡単な例を次に示します。
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
結果:
(7 rows affected) Msg 3902, Level 16, State 1, Line 2 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
これは、SET IMPLICIT_TRANSACTIONS
の場合に発生します OFF
です 。 SET IMPLICIT_TRANSACTIONS
の場合は、以下を参照してください。 ON
です 。
エラー処理によるエラーの例
エラー処理を実装し、コード内の他の場所でトランザクションをすでにコミットまたはロールバックしていることを忘れているために、これが発生している可能性があります。
例:
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;
結果:
(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.
この場合、私はすでにCOMMIT TRANSACTION
を持っていました TRY
で ブロック。したがって、2番目のCOMMIT TRANSACTION
までに が検出された場合、トランザクションはすでにコミットされています。
トランザクションでエラーが発生し、ロールバックされた場合でも、同じことがわかります。ロールバックするとトランザクションが終了するため、これ以上COMMIT
は発生しません。 ステートメントが必要です。
したがって、この問題を修正するには、最後のCOMMIT TRANSACTION
を削除するだけです。 、およびトランザクションコードは次のようになります:
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
暗黙のトランザクション
暗黙のトランザクションを有効にしている場合、最初の例とは異なる結果が得られる可能性があります。
IMPLICIT_TRANSACTIONS
を設定した場合 ON
へ 、これが私たちが得るものです:
SET IMPLICIT_TRANSACTIONS ON;
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
結果:
+---------------------------------+----------------+ | 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)
エラーは発生しません。
これは、特定のT-SQLステートメントが実行されると自動的にトランザクションを開始するためです。見えないBEGIN TRANSACTION
が前に付いているかのようです ステートメント。
IMPLICIT_TRANSACTIONS
の場合 OFF
です 、これらのステートメントは自動的にコミットされます。目に見えないCOMMIT TRANSACTION
が成功したかのようです 声明。このシナリオでは、トランザクションは自動コミットモードになっています。
IMPLICIT_TRANSACTIONS
の場合 ON
です 、目に見えないCOMMIT TRANSACTION
はありません 声明。これらのステートメントは、まだ非表示のBEGIN TRANSACTION
によって開始されます 、ただし、明示的に終了する必要があります。
暗黙的なトランザクションは、明示的にコミットされるか、明示的にロールバックされるまで進行中です。
したがって、この例では、迷子のCOMMIT TRANSACTION
暗黙のトランザクションを終了するには、ステートメントが実際に必要でした。