SQLServerには4つのトランザクションモードがあります。これらの1つは暗黙的なモードです。
SQL Serverでは、暗黙的なトランザクションとは、前のトランザクションが完了したときに新しいトランザクションが暗黙的に開始されることですが、各トランザクションはCOMMIT
で明示的に完了します。 またはROLLBACK
ステートメント。
これは、トランザクションが暗黙的に開始および終了される自動コミットモードと混同しないでください。
4つのトランザクションモード
SQL Serverは、次のトランザクションモードで動作できます。
トランザクションモード | 説明 |
---|---|
トランザクションの自動コミット | 個々のステートメントはトランザクションです。 |
暗黙のトランザクション | 新しいトランザクションは、前のトランザクションが完了すると暗黙的に開始されますが、各トランザクションは、通常はCOMMIT を使用して明示的に完了します。 またはROLLBACK DBMSに応じたステートメント。 |
明示的なトランザクション | START TRANSACTION などの行で明示的に開始 、BEGIN TRANSACTION または同様のもので、DBMSに応じて、関連するステートメントで明示的にコミットまたはロールバックされます。 |
バッチスコープのトランザクション | 複数のアクティブな結果セット(MARS)にのみ適用されます。 MARSセッションで開始される明示的または暗黙的なトランザクションは、バッチスコープのトランザクションになります。 |
暗黙モードと自動コミット
SQL Serverでは、特定のステートメントが実行されると、トランザクションが自動的に開始されます。見えないBEGIN TRANSACTION
が前に付いているかのようです ステートメント。
ほとんどの場合、これらのトランザクションも、目に見えないCOMMIT TRANSACTION
があったかのように、暗黙的にコミットされます。 声明。このようなトランザクションは、自動コミットモードであると言われます 。
その他の場合、目に見えないCOMMIT TRANSACTION
はありません 目に見えないBEGIN TRANSACTION
と一致させる 声明。トランザクションは、明示的にコミットするか、COMMIT TRANSACTION
でロールバックするまで、進行中のままです。 またはROLLBACK TRANSACTION
声明。この場合、トランザクションは暗黙モードであると言われます 。
トランザクションが暗黙モードで実行されるか自動コミットモードで実行されるかは、IMPLICIT_TRANSACTIONS
によって異なります。 設定。
暗黙のトランザクションを開始するステートメント
次のステートメントは、SQLServerで暗黙的なトランザクションを開始します。
-
ALTER TABLE
-
BEGIN TRANSACTION
-
CREATE
-
DELETE
-
DROP
-
FETCH
-
GRANT
-
INSERT
-
OPEN
-
REVOKE
-
SELECT
(SELECT GETDATE()
など、テーブルから選択しないものを除く またはSELECT 1*1
) -
TRUNCATE TABLE
-
UPDATE
これらのT-SQLステートメントを実行するときはいつでも、トランザクションを開始します。ほとんどの場合、トランザクションは自動的にコミットされます。したがって、明示的に行う必要なしにトランザクションを開始および終了しました。
ただし、IMPLICIT_TRANSACTIONS
によっては 設定すると、トランザクションを明示的にコミットする必要がある場合があります。
IMPLICIT_TRANSACTIONS
の場合 OFF
です
IMPLICIT_TRANSACTIONS
の場合 設定はOFF
、上記のステートメントは、自動コミットモードでトランザクションを実行します。つまり、とを開始します トランザクションを暗黙的に終了します。
つまり、BEGIN TRANSACTION
が見えないようなものです。 ステートメントと非表示のCOMMIT TRANSACTION
ステートメント、すべて1つのステートメントから。
この場合、トランザクションをコミットまたはロールバックするために何もする必要はありません。すでに完了しています。
IMPLICIT_TRANSACTIONS
の場合 ON
です
IMPLICIT_TRANSACTIONS
の場合 設定はON
、上記のステートメントの動作は少し異なります。
IMPLICIT_TRANSACTIONS
の場合 設定はON
、上記のステートメントは非表示のBEGIN TRANSACTION
を取得します ステートメントですが、対応するCOMMIT TRANSACTION
を取得しません ステートメント。
これは、トランザクションを自分で明示的にコミットまたはロールバックする必要があることを意味します。
ただし、トランザクションモードが暗黙的である場合、非表示のBEGIN TRANSACTION
はありません。 トランザクションがすでに進行中の場合に発行されます。
例
コンセプトを示す例を次に示します。
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS OFF;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
結果:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
この場合、IMPLICIT_TRANSACTIONS
を設定します OFF
へ SELECT
を実行します 声明。これは、SELECT
ステートメントは自動コミットモードで実行されたため、トランザクションは暗黙的に開始および終了しました。
@@TRANCOUNT
返された0
、つまり、その時点で実行されているトランザクションはありませんでした。
今回もIMPLICIT_TRANSACTIONS
を設定したことを除いて、ここにあります。 ON
へ 。
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
結果:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 1 | +--------------------+ (1 row affected)
最後の@@TRANCOUNT
1
の値を返しています 。これは、トランザクションがまだ進行中であることを意味します。
@@TRANCOUNT
BEGIN TRANSACTION
の数を返します 現在の接続で発生したステートメント。明示的に発行したわけではありませんが、暗黙的に発行されました。
したがって、@@TRANCOUNT
をデクリメントするには、実際にこのトランザクションをコミットする(またはロールバックする)必要があります。 0
まで 。
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
結果:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
したがって、暗黙的なトランザクションのコードには、COMMIT
が含まれている必要があります。 ステートメント:
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
結果:
+--------------------+ | 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
暗黙のトランザクションが予期せず有効になっている場合は、ANSI_DEFAULTS
が原因である可能性があります。 設定。