【SQL & データベース入門】トランザクションとロールバック|データ整合性を保つ仕組みを理解しよう

トランザクションとは何か?

トランザクションの概要

トランザクションとは、データベースにおける一連の操作をまとめて一つの処理単位として扱う仕組みです。この処理単位はすべての操作が正常に完了するか、もしくはすべての操作が無効になるかのどちらかで終わります。たとえば、銀行の口座間での送金処理では、送金元の残高を減らし、送金先の残高を増やす操作が一連のトランザクションとして扱われます。

トランザクションの4つの特性(ACID特性)

トランザクションは、以下の4つの特性を満たす必要があります:

  • Atomicity(原子性):トランザクション内のすべての操作は一体となって実行されるか、全く実行されないかのどちらかです。
  • Consistency(一貫性):トランザクションが完了すると、データベースは一貫性のある正しい状態になります。
  • Isolation(分離性):複数のトランザクションが同時に実行される場合でも、それぞれのトランザクションが互いに干渉しないようにします。
  • Durability(耐久性):トランザクションが完了した後、その結果は永続的に保存されます。

トランザクションの基本操作

BEGIN(トランザクションの開始)

トランザクションを開始するために使用されるコマンドです。データベースはここからトランザクションを開始し、すべての操作を一つの単位として扱います。

BEGIN;

COMMIT(トランザクションの確定)

トランザクション内のすべての操作をデータベースに反映するためのコマンドです。

COMMIT;

ROLLBACK(トランザクションの取り消し)

トランザクション内で行われたすべての変更を取り消して、トランザクション開始前の状態に戻します。

ROLLBACK;

実際の使用例

銀行の口座間で送金を行うトランザクションの例です。

BEGIN;

-- 送金元の残高を減らす
UPDATE accounts SET balance = balance - 5000 WHERE account_id = 1;

-- 送金先の残高を増やす
UPDATE accounts SET balance = balance + 5000 WHERE account_id = 2;

-- すべての操作が正常に完了したらコミット
COMMIT;

エラーが発生した場合は ROLLBACK を使用して変更を取り消すことができます。

ロールバックとは何か?

ロールバックの概要

ロールバックとは、トランザクション内で行われたすべての変更を取り消し、データベースをトランザクション開始前の状態に戻す操作です。ロールバックは、エラーや異常が発生した際にデータの一貫性を保つために重要です。

実際の使用例

たとえば、次のような操作中にエラーが発生した場合、ロールバックを使って変更を取り消します。

BEGIN;

-- 送金元の残高を減らす
UPDATE accounts SET balance = balance - 5000 WHERE account_id = 1;

-- 送金先の残高を増やす(ここでエラーが発生したと仮定)
UPDATE accounts SET balance = balance + 5000 WHERE account_id = 2;

-- エラー発生時にロールバック
ROLLBACK;

この例では、ロールバックによって最初の更新操作も取り消され、トランザクション開始前の状態に戻ります。

SAVEPOINTとROLLBACK TOの活用

SAVEPOINTとは

SAVEPOINTは、トランザクション内で部分的にロールバックを行いたい場合に使用されるマークポイントです。トランザクションの途中でSAVEPOINTを設定し、そのポイントまでロールバックすることができます。

基本構文

SAVEPOINT savepoint_name;

ROLLBACK TOの基本構文

ROLLBACK TO savepoint_name;

実際の使用例

次の例では、部分的なロールバックを行います。

BEGIN;

-- 操作1
UPDATE accounts SET balance = balance - 1000 WHERE account_id = 1;

-- セーブポイントを設定
SAVEPOINT sp1;

-- 操作2(エラーが発生したと仮定)
UPDATE accounts SET balance = balance + 1000 WHERE account_id = 2;

-- エラーが発生したためセーブポイントまでロールバック
ROLLBACK TO sp1;

-- 操作1のみが有効な状態で残る
COMMIT;

この例では、操作1のみが確定され、操作2の変更は取り消されます。

トランザクションの分離レベル

分離レベルの概要

分離レベルは、同時に実行される複数のトランザクションが互いにどの程度干渉を許すかを決定する設定です。分離レベルを適切に設定することで、データの整合性を保ちながらパフォーマンスを最適化できます。

分離レベルの種類

  • READ UNCOMMITTED:他のトランザクションがコミットしていないデータも読み取ることができます。
  • READ COMMITTED:他のトランザクションがコミットしたデータのみを読み取ります。
  • REPEATABLE READ:トランザクション開始時点でのデータを一貫して読み取ります。
  • SERIALIZABLE:すべてのトランザクションを直列に実行するように見なします。

設定方法

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

トランザクションとロールバックの実用例

ECサイトでの注文処理

ユーザーが注文を確定する際には、在庫の減少や支払い情報の更新が複数のステップにわたって行われます。この一連の操作をトランザクションとしてまとめ、途中でエラーが発生した場合はロールバックすることでデータの整合性を保つことができます。

BEGIN;

-- 在庫の更新
UPDATE products SET stock = stock - 1 WHERE product_id = 101;

-- 注文情報の挿入
INSERT INTO orders (order_id, product_id, quantity) VALUES (1, 101, 1);

-- 支払い処理(仮にエラーが発生したとする)
UPDATE payments SET status = 'paid' WHERE payment_id = 1001;

-- エラーが発生したためロールバック
ROLLBACK;

まとめ

トランザクションとロールバックは、データベースの整合性と信頼性を確保するための重要な機能です。トランザクションは、複数の操作を一つの単位として扱い、すべての操作が正常に完了した場合のみ確定されます。一方、ロールバックは異常が発生した際にデータの変更を元に戻すことで、データの一貫性を保つ役割を果たします。SAVEPOINTや分離レベルの設定を適切に組み合わせることで、複雑なシステムでも安全かつ効率的なデータ操作が可能になります。