トランザクションの自動コミット

自動コミット モードは、SQL Server データベース エンジンの既定のトランザクション管理モードです。すべての Transact-SQL ステートメントは完了時にコミットされるか、ロールバックされます。ステートメントが正常に完了した場合はコミットされ、エラーが検出された場合はロールバックされます。この既定のモードを明示的トランザクションまたは暗黙のトランザクションで上書きした場合を除いて、データベース エンジンのインスタンスへの接続は自動コミット モードで動作します。ADO、OLE DB、ODBC、および DB-Library の既定モードも自動コミット モードです。

データベース エンジンのインスタンスへの接続は、BEGIN TRANSACTION ステートメントによって明示的なトランザクションが開始されるか、暗黙のトランザクションがオンに設定されるまで、自動コミット モードで動作します。明示的なトランザクションがコミットまたはロールバックされるか、暗黙のトランザクション モードがオフになると、接続は自動コミット モードに戻ります。

SET IMPLICIT_TRANSACTIONS が ON の場合は、接続は暗黙のトランザクション モードに設定されます。OFF の場合、接続は自動コミット トランザクション モードに戻ります。

コンパイル エラーと実行時エラー

自動コミット モードの場合、データベース エンジンのインスタンスが 1 つの SQL ステートメントだけでなく、バッチ全体をロールバックしたように見える場合があります。これは、検出されたエラーが実行時エラーではなくコンパイル エラーの場合に発生します。コンパイル エラーが起きると、データベース エンジンの実行プランが構築できず、バッチ内のどの処理も実行されません。エラーを生成したステートメントよりも前にあるすべてのステートメントがロールバックされたように見えますが、エラーによりバッチ内のどのステートメントも実行されませんでした。次の例では、3 番目のバッチ内のどの INSERT ステートメントも、コンパイル エラーにより実行されません。最初の 2 つの INSERT ステートメントが実行されないので、ロールバックされたように見えます。

USE AdventureWorks2008R2;
GO
CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3));
GO
INSERT INTO TestBatch VALUES (1, 'aaa');
INSERT INTO TestBatch VALUES (2, 'bbb');
INSERT INTO TestBatch VALUSE (3, 'ccc');  -- Syntax error.
GO
SELECT * FROM TestBatch;  -- Returns no rows.
GO

次の例では、3 番目の INSERT ステートメントによって、主キーが重複するという実行時エラーが生成されます。最初の 2 つの INSERT ステートメントは正常に完了しコミットされるので、実行時エラーの生成後も有効です。

USE AdventureWorks2008R2;
GO
CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3));
GO
INSERT INTO TestBatch VALUES (1, 'aaa');
INSERT INTO TestBatch VALUES (2, 'bbb');
INSERT INTO TestBatch VALUES (1, 'ccc');  -- Duplicate key error.
GO
SELECT * FROM TestBatch;  -- Returns rows 1 and 2.
GO

データベース エンジンでは、名前の遅延解決を採用しています。つまり、オブジェクト名は実行時まで解決されません。次の例では、最初の 2 つの INSERT ステートメントは正常に実行されてコミットされ、3 番目の INSERT ステートメントで存在しないテーブルが参照され、実行時エラーになった後も、最初の 2 行は TestBatch テーブル内に残ります。

USE AdventureWorks2008R2;
GO
CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3));
GO
INSERT INTO TestBatch VALUES (1, 'aaa');
INSERT INTO TestBatch VALUES (2, 'bbb');
INSERT INTO TestBch VALUES (3, 'ccc');  -- Table name error.
GO
SELECT * FROM TestBatch;  -- Returns rows 1 and 2.
GO