📑

データベースの信頼性を支える「トランザクション」とは?

に公開

はじめに

データベース管理システム(DBMS)の根幹を支える考え方「トランザクション」。
英語で書くと、Tranzaction略してTX。
複数のSQL文を一つの論理的な「塊」として扱い、データの一貫性と信頼性を保証する仕組みです。

この記事では、銀行の口座AからBへの送金を例に考えてみます。
「Aから減額する」と「Bに増額する」という2つのステップにおいて
前者が成功し、後者がシステム障害で失敗した場合、どうなるでしょうか。

Aさんはの残高が減って、Bさんの残高が増えていないという、データが不整合な状態に陥ります。
間違いなくケンカが起きるでしょう。
こういったことを起こさないためにあるのが、トランザクションなんです。
あなたのPayPayで割り勘した際の送金も、トランザクションによってちゃんと処理されるわけです。

1. トランザクションのルール

DBMSがこの「塊」に対して厳格に適用する2つのルール(原則)を理解しましょう。
ここはトランザクションを学ぶ上で最も重要なポイントです。

  • トランザクションにとっての最優先ルール
  1. 処理の中断を許さない:トランザクションの途中でシステム障害やエラーが発生しても、処理を中途半端な状態で放置しない
  2. 他者の割り込みを許さない:あるトランザクションが実行中に、他のユーザーの処理がデータの整合性を乱すような割り込みをしない

これらのルールによって、トランザクションは「すべて実行する」か「一つも実行していない(最初からなかったことにする)」のどちらかの状態にしかなりません。この不可分な性質を、トランザクションの「原子性(Atomicity)」と呼びます。

トランザクションの操作

トランザクションを実行するには、実際どのような操作が必要になるのでしょうか。
データの確定と取り消しを制御する操作について解説します。

  • トランザクションは、実行中のデータ操作を一時的に「仮の状態」として管理します。
    この仮の状態を「確定」させたり「取り消し」たりすることで、原子性を実現しています。

【コード例】

BEGIN; -- トランザクション開始

-- 1. 口座Aから1000円を減額
UPDATE accounts SET balance = balance - 1000 WHERE account_id = 'A';

-- 2. 口座Bへ1000円を増額
UPDATE accounts SET balance = balance + 1000 WHERE account_id = 'B';

COMMIT; -- 処理が成功した場合、変更を確定(永続化)

もし、2番目のUPDATE文の途中でエラーが発生した場合、
DBMSは自動的、またはエラー処理によって、最初のUPDATEを含めたすべての処理をROLLBACKし、
データはトランザクション開始前の状態に戻ります

補足知識:エラー処理とCATCHの重要性

より堅牢なトランザクション処理では、
BEGINとCOMMITの間でエラーが発生した場合に備え、意図的にROLLBACKを行う仕組みが必要です。
SQLのプロシージャや処理環境によっては、CATCH句(またはそれに相当するエラーハンドリング機構)が重要な役割を果たします。

BEGIN TRY
    BEGIN;
    -- 重要なSQL処理...
    COMMIT;
END TRY
BEGIN CATCH
    -- エラーを捕捉した場合
    ROLLBACK; -- 確定せずに変更をなかったことにする
    -- エラーログの記録など
END CATCH

これは、「処理が失敗しても、データは破壊せず元に戻す」というトランザクションのルールを守るための重要なテクニックとなります。

★Gitのコミットとの親和性

ところで、「コミット」と聞くとGitのコミットとどう違うのか気になりませんか。
その点についても最後にお話ししようと思います。

結論からお伝えすると、どちらも、複数の変更を「ひとまとまりの確定状態」として記録し、システムや履歴の信頼性を保証するという点で、根本的な概念が共通しています。

  • SQLのCOMMIT: 複数の変更(SQL文)を「仮の状態」から「データベースに永続的に反映された確定状態」に移行させ、その変更を不可分な一つの単位として固定します。

  • GitのCOMMIT: 複数のファイルへの変更を「ステージングエリアの仮の状態」から「リポジトリの履歴に永続的に反映された確定状態」に移行させ、その変更を不可分な一つの単位(スナップショット)として固定します。

このように、SQLのトランザクションのCOMMITGitのコミットcommit)は、全く同じものではありませんが、非常に高い親和性(イメージの類似性)を持っています。

Gitのコミットも、トランザクションの原子性と同様に「すべて記録」されるか「記録されない」かのどちらかであり、途中で中途半端に記録されることはありません。
この共通の概念が、プログラミングやデータ管理において重要な「変更の永続化と信頼性の確保」という考え方を理解する手助けとなるでしょう。

以上、本日はトランザクションについての記事でした。
この仕組みが、金融システムからECサイトに至るまで、あらゆるデジタルデータの信頼性を根底で支えているんですね。

良ければまた明日も見に来てください。
ここまでお読みいただきありがとうございました!

Discussion