SQLでINSERT、UPDATE、DELETEを実行するとき、「処理内容を確認してからデータベースへ反映したい」と考えることがあります。

そのような場合に使用するのが、トランザクションを確定するCOMMITです。

COMMITを使用すると、複数のSQL処理をひとまとまりにして実行し、すべて問題なければ変更を確定できます。反対に、処理を取り消したい場合はROLLBACKを使用します。

この記事では、SQL Server Management Studioを使用して、BEGIN TRANSACTIONからCOMMITまでの基本的な流れを実際に動かしながら解説します。

サンプル用のデータベースとテーブルを作成し、UPDATEしたデータをCOMMITで確定するところまで確認するため、SQL初心者でも順番に進められます。

この記事でわかること

この記事では、SQL Server Management Studioを使ってCOMMITを実際に実行する方法を確認します。

  • COMMITとトランザクションの基本的な役割
  • SQL Server LocalDBへSSMSから接続する方法
  • 練習用データベースとテーブルの作成方法
  • BEGIN TRANSACTIONの使い方
  • UPDATEしたデータをCOMMITで確定する方法
  • COMMIT前後のデータを確認する方法
  • COMMIT忘れや誤更新を防ぐための注意点

COMMITだけでなく、対になるROLLBACKとの違いも確認します。

※トランザクションについては以下の記事を参考にしてください。

動作環境

この記事では、Windows環境でSQL Server LocalDBとSSMSを使う前提で進めます。

バージョンは一例です。環境によって画面表示や細かい操作が異なる場合があります。

項目内容
OSWindows 11
SQL ServerSQL Server LocalDB
管理ツールSQL Server Management Studio(SSMS)
接続先(LocalDB)\MSSQLLocalDB
使用言語SQL

環境構築ができていない場合は、以下を参考にしてください。
また、C#.NETで実行したい方は本記事と以下の記事を見ながら試行してみてください。

完成イメージ

この記事では、Productsテーブルに登録されている商品の価格をUPDATE文で変更します。

ただし、UPDATE文をそのまま確定するのではなく、BEGIN TRANSACTIONでトランザクションを開始してから更新します。

処理の流れは次のとおりです。

  1. Productsテーブルの更新前データを確認する
  2. BEGIN TRANSACTIONでトランザクションを開始する
  3. UPDATE文で商品の価格を変更する
  4. SELECT文で更新結果を確認する
  5. 問題がなければCOMMITで変更を確定する
  6. COMMIT後にデータを再確認する

最終的には、商品IDが1の商品について、価格が1000円から1200円へ変更され、COMMIT後も変更内容が保持されている状態を確認します。

ProductIdProductNamePrice
1キーボード1200
2マウス1500
3モニター30000

COMMITの実践

ここからは、SSMSを使用してCOMMITを実際に動かす手順を解説します。

手順を上から順番に進めれば、テーブル作成から更新結果の確認まで実行できます

学習用データベースを作成する

まずは、COMMITを確認するために、学習用データベースを作成します。

SSMSで新しいクエリを開き、以下のSQLを実行します。

CREATE DATABASE CommitDB;

実行後、左側のデータベース一覧を更新すると、CommitDBが表示されます。

CommitDBの作成画像

作成したデータベースを使うために、以下のSQLも実行します。

USE CommitDB;

これで、以降のSQLはCommitDBに対して実行されます。

Productsテーブルを作成する

次に、商品情報を保存するProductsテーブルを作成します。

このテーブルには、商品ID、商品名、価格を保存します。

次のSQLを実行してください。

CREATE TABLE dbo.Products
(
    ProductId INT NOT NULL PRIMARY KEY,
    ProductName NVARCHAR(100) NOT NULL,
    Price INT NOT NULL
);

Productsテーブルの構成は次のとおりです。

列名データ型内容
ProductIdINT商品を識別するID
ProductNameNVARCHAR(100)商品名
PriceINT商品価格

ProductIdにはPRIMARY KEYを設定しています。そのため、同じProductIdを重複して登録することはできません

テーブル作成画像

また、今回のSQLでは実行結果を揃えるため、Productsテーブルがすでに存在する場合は削除してから作り直しています。

サンプルデータを登録する

作成したProductsテーブルへ、確認用のデータを3件登録します。

次のINSERT文を実行してください。

INSERT INTO dbo.Products
(
    ProductId,
    ProductName,
    Price
)
VALUES
    (1, N'キーボード', 1000),
    (2, N'マウス', 1500),
    (3, N'モニター', 30000);

行後に「4行に影響しました」などと表示されれば、サンプルデータの登録は完了です。

テーブルデータの登録画像

実行後、SELECT文で登録結果を確認します。

SELECT
    ProductId,
    ProductName,
    Price
FROM dbo.Products
ORDER BY ProductId;

次のような結果が表示されれば、問題ありません。

テーブルデータの登録確認画像

これ以降は、ProductIdが1のキーボードを対象にして、価格を1000円から1200円へ変更します。

COMMITの基本構文を確認する

SQL Serverで明示的なトランザクションを使用する場合は、BEGIN TRANSACTIONで処理を開始します。
その後、INSERT、UPDATE、DELETEなどを実行し、問題がなければCOMMIT TRANSACTIONで変更を確定します。

基本構文は次のとおりです。

BEGIN TRANSACTION;

-- INSERT、UPDATE、DELETEなどの処理

COMMIT TRANSACTION;

短縮して、次のように記述することもできます。

BEGIN TRAN;

-- INSERT、UPDATE、DELETEなどの処理

COMMIT;

この記事では、処理内容がわかりやすいように、BEGIN TRANSACTIONとCOMMIT TRANSACTIONを使用します。

BEGIN TRANSACTIONからCOMMIT TRANSACTIONまでが、ひとまとまりの処理になります。

BEGIN TRANSACTIONで処理を開始する

ここから、実際にトランザクションを使用してデータを更新します。

最初に、次のSQLを実行してください。

BEGIN TRANSACTION;

BEGIN TRANSACTIONを実行すると、明示的なトランザクションが開始されます。

この時点では、まだデータを更新していません。

現在のトランザクション数を確認したい場合は、次のSQLを実行します。

SELECT @@TRANCOUNT AS TransactionCount;

結果が1の場合は、現在のセッションでトランザクションが1つ開始されています。

BEGIN TRANSACTIONで処理を開始する画像

この後のUPDATE文とCOMMIT文は、同じクエリウィンドウで実行してください
別のクエリウィンドウを開くと、別のセッションとして扱われます。

UPDATE文でデータを変更する

トランザクションを開始した状態で、ProductIdが1の商品の価格を変更します。

次のUPDATE文を実行してください。

UPDATE dbo.Products
SET Price = 1200
WHERE ProductId = 1;

WHERE句では、更新対象をProductIdが1のデータに限定しています。

UPDATE文でデータを変更する画像

UPDATE文を実行すると、「1行処理されました」と表示されます。

ただし、この時点ではまだCOMMITを実行していないため、トランザクションは終了していません

※WHERE句を付け忘れると、Productsテーブル内のすべての商品の価格が1200に変更されます。

COMMIT前のデータを確認する

COMMITを実行する前に、SELECT文で変更内容を確認します。

次のSQLを実行してください。

SELECT
    ProductId,
    ProductName,
    Price
FROM dbo.Products
WHERE ProductId = 1;

実行結果では、キーボードの価格が1200になっています。

COMMIT前のデータを確認する画像

同じクエリウィンドウでは、トランザクション内で変更した内容を確認できます。
この段階で更新内容に問題がないか確認し、問題がなければCOMMITを実行します。

つまり、COMMIT前のSELECTは、変更内容を確定する前の最終確認として使用できます。

COMMITで変更を確定する

更新内容に問題がなければ、次のSQLを実行します。

COMMIT TRANSACTION;

COMMIT TRANSACTIONを実行すると、BEGIN TRANSACTION以降に行った変更が確定します。

今回の場合は、キーボードの価格を1000円から1200円へ変更した内容が、データベースへ正式に反映されます。

トランザクションが終了したことを確認するには、次のSQLを実行してください。

SELECT @@TRANCOUNT AS TransactionCount;

COMMITが正常に実行されていれば、結果は0になります。

COMMITで変更を確定する画像

@@TRANCOUNTが0であることは、現在のセッションに未完了のトランザクションがない状態を表します。

COMMIT後のデータを確認する

最後に、Productsテーブルのデータをもう一度確認します。

次のSELECT文を実行してください。

SELECT
    ProductId,
    ProductName,
    Price
FROM dbo.Products
ORDER BY ProductId;

実行結果は次のようになります。

COMMIT後のデータを確認する画像

ProductIdが1の価格が1200になっていれば、COMMITによる変更の確定は完了です。

COMMIT後はクエリウィンドウを閉じたり、SSMSを再起動したりしても、変更後のデータが保持されます。

一連の処理をまとめて実行する

ここまでのトランザクション処理を1つにまとめると、次のようになります。

BEGIN TRANSACTION;

UPDATE dbo.Products
SET Price = 1200
WHERE ProductId = 1;

SELECT
    ProductId,
    ProductName,
    Price
FROM dbo.Products
WHERE ProductId = 1;

COMMIT TRANSACTION;

SELECT
    ProductId,
    ProductName,
    Price
FROM dbo.Products
ORDER BY ProductId;

このSQLでは、UPDATE後にSELECTで変更内容を確認しています。

一連の処理をまとめて実行する画像

ただし、SQL全体を一度に実行すると、確認結果を見る前にCOMMITまで実行されます。

実際に確認しながら進める場合は、BEGIN TRANSACTION、UPDATE、SELECT、COMMITを分けて実行してください。

業務データを更新する場合は、一括実行よりも段階的に実行した方が安全です。

ROLLBACKとの違いを確認する

更新内容を確定したくない場合は、COMMITではなくROLLBACKを使用します。

ROLLBACKについては以下の記事を参考にしてください。

TRY…CATCHでエラー時にROLLBACKする

複数のSQLを1つのトランザクションで実行する場合は、途中でエラーが発生する可能性があります。エラーが発生したときにトランザクションを残さないように、TRY…CATCHを使用できます。

次のSQLでは、正常に処理できた場合はCOMMITし、エラーが発生した場合はROLLBACKします。

SET XACT_ABORT ON;

BEGIN TRY
    BEGIN TRANSACTION;

    UPDATE dbo.Products
    SET Price = 1300
    WHERE ProductId = 1;

    UPDATE dbo.Products
    SET Price = 1600
    WHERE ProductId = 2;

    COMMIT TRANSACTION;

    PRINT N'更新処理を確定しました。';
END TRY

BEGIN CATCH
    IF XACT_STATE() <> 0
    BEGIN
        ROLLBACK TRANSACTION;
    END;

    SELECT
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_MESSAGE() AS ErrorMessage;

    THROW;
END CATCH;

BEGIN TRY内でエラーが発生すると、処理はBEGIN CATCHへ移動します。

TRY...CATCHでエラー時にROLLBACKする画像

XACT_STATE関数でトランザクションが残っているか確認し、残っている場合はROLLBACKします。

このように、実際の更新処理では正常時はCOMMIT、異常時はROLLBACKという構成にすると、安全性を高められます。

よくあるエラー・注意点

COMMITを使用するときは、トランザクションを開始したまま放置しないことが重要です。

初心者がつまずきやすいエラーと確認ポイントをまとめます。

エラー・状況主な原因対処法
COMMITを実行するとエラーになるBEGIN TRANSACTIONを実行していないCOMMITの前にBEGIN TRANSACTIONが実行されているか確認する
更新内容が元に戻らないすでにCOMMITを実行しているCOMMIT後は通常ROLLBACKできないため、確定前にSELECTで確認する
別の画面からデータを更新できないトランザクションによるロックが残っているCOMMITまたはROLLBACKを実行し、トランザクションを終了する
@@TRANCOUNTが0にならないBEGIN TRANSACTIONとCOMMITの数が合っていない@@TRANCOUNTを確認し、処理の対応関係を見直す
すべての行が更新されたUPDATE文のWHERE句を付け忘れた先にSELECT文で更新対象を確認する
COMMIT前の変更が別画面に表示されない別セッションでは未確定データを通常参照できない同じクエリウィンドウで確認するか、COMMIT後に再確認する
オブジェクト名が無効と表示される使用中のデータベースが異なるUSE文またはSSMS上部のデータベース選択欄を確認する
クエリウィンドウを閉じると警告が出る未完了のトランザクションが残っている可能性がある@@TRANCOUNTを確認し、COMMITまたはROLLBACKを実行する

特に注意したいのが、COMMITの実行忘れです。

BEGIN TRANSACTIONを開始したままにすると、更新対象のデータにロックが残り、別のクエリやアプリケーションの処理が待たされる場合があります。

作業の最後には、次のSQLで未完了のトランザクションが残っていないか確認してください。

SELECT @@TRANCOUNT AS TransactionCount;

結果が0であれば、現在のセッションに未完了の明示的トランザクションはありません。

COMMIT後はROLLBACKできない

COMMITを実行すると、トランザクション内の変更が確定します。

確定後にROLLBACKを実行しても、通常はCOMMIT前の状態へ戻せません。

そのため、COMMITを実行する前に、SELECT文で対象件数と変更後の値を確認してください。

特にUPDATE文やDELETE文では、WHERE句の条件が正しいかを慎重に確認する必要があります。

トランザクションは短時間で終了する

トランザクションの実行中は、処理内容によってテーブルや行にロックがかかります。

トランザクションを長時間開いたままにすると、他のユーザーや処理が対象データへアクセスできなくなる場合があります。

そのため、BEGIN TRANSACTIONを実行した後は、必要な確認を行って速やかにCOMMITまたはROLLBACKしてください。

長時間の離席や別作業を挟むことは避けましょう。

BEGIN TRANSACTIONとCOMMITは同じ画面で実行する

SSMSでは、クエリウィンドウごとに異なる接続セッションが使用される場合があります。

クエリウィンドウAでBEGIN TRANSACTIONを実行し、クエリウィンドウBでCOMMITを実行しても、Aのトランザクションは終了できません。

基本的には、開始から確定または取消まで同じクエリウィンドウで実行してください。

接続やセッションの動作は、SSMSの設定や接続状態によって異なる場合があります。

SQL Serverは通常1文ごとに自動確定される

BEGIN TRANSACTIONを明示的に使用していない通常の状態では、UPDATE文などは1文単位のトランザクションとして処理されます。

そのため、次のUPDATE文だけを実行した場合、後からROLLBACKを書いても元に戻せません。

UPDATE dbo.Products
SET Price = 2000
WHERE ProductId = 1;

確定前に内容を確認したい場合は、UPDATE文の前にBEGIN TRANSACTIONを実行する必要があります。

BEGIN TRANSACTION;

UPDATE dbo.Products
SET Price = 2000
WHERE ProductId = 1;

SELECT
    ProductId,
    ProductName,
    Price
FROM dbo.Products
WHERE ProductId = 1;

ROLLBACK TRANSACTION;

この流れを使用すれば、更新結果を確認した後で、COMMITするかROLLBACKするかを判断できます。

まとめ

この記事では、SQL Server Management Studioを使用して、COMMITでトランザクションを確定する方法を解説しました。

今回の重要なポイントは次のとおりです。

  • BEGIN TRANSACTIONで明示的なトランザクションを開始する
  • INSERT、UPDATE、DELETEなどの変更処理を実行する
  • COMMIT前にSELECT文で変更内容を確認する
  • 問題がなければCOMMIT TRANSACTIONで確定する
  • 変更を取り消す場合はROLLBACK TRANSACTIONを使用する
  • @@TRANCOUNTで未完了のトランザクションを確認できる
  • トランザクションを長時間開いたままにしない

COMMITは、複数のデータ更新をまとめて確定するときに欠かせない命令です。

ただし、一度COMMITした変更は通常ROLLBACKで戻せないため、確定前の確認が重要です。

次は、ROLLBACKの使い方や、TRY…CATCHを使用したトランザクションのエラー処理について学ぶと、より安全なSQL更新処理を作成できるようになります。