Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】💾 Transactions, Deadlocks & Log-Based Recovery (Hands-on SQL Guide)

2025年10月03日に「Dev.to」が公開したITニュース「💾 Transactions, Deadlocks & Log-Based Recovery (Hands-on SQL Guide)」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

データベースはACID特性でデータ一貫性を保証する。記事では、トランザクションの原子性による全か無かの処理、複数の操作が互いに待ち合うデッドロック、ログを用いた障害時のデータ復旧(リカバリ)の仕組みをSQLの具体例で分かりやすく解説する。

ITニュース解説

データベースは、私たちが日常的に利用する様々なシステムにおいて、情報を安全かつ正確に管理するための基盤となる。その中心的な役割は、大量のデータを矛盾なく保持し、いつでも取り出せる状態に保つことだ。これを実現するため、データベースにはACID特性と呼ばれる重要な性質が備わっている。特に、データの一貫性と信頼性を保証する上で、「トランザクション」「デッドロック」「ログベースリカバリ」という三つの概念が非常に重要となる。

まず、トランザクションは、複数のデータベース操作を一つのまとまりとして扱う仕組みだ。例えば、銀行でAliceの口座からBobの口座へ送金する場合を考えてみよう。この操作は、「Aliceの口座から金額を引く」と「Bobの口座に金額を足す」という二つのステップから成り立っている。もし途中でシステムが停止したり、エラーが発生したりした場合、Aliceの口座からだけ金額が引かれ、Bobの口座には入金されないといった不整合が起きてしまう可能性がある。このような事態を防ぐために、トランザクションの「原子性(Atomicity)」という特性が活躍する。原子性とは、「全か無か」の原則とも呼ばれ、トランザクション内のすべての操作が成功するか、あるいは一つも適用されないかのどちらかであることを保証する。

具体例として、SQLを使ってAliceからBobへ500の金額を移動する操作を考えてみる。まずBEGINコマンドでトランザクションを開始する。次に、UPDATE Accounts SET balance = balance - 500 WHERE name = 'Alice';というSQL文でAliceの残高から500を減らし、続いてUPDATE Accounts SET balance = balance + 500 WHERE name = 'Bob';でBobの残高に500を加える。この時点では、変更はまだ一時的なもので、データベースに永続的に反映されたわけではない。もしここで、何らかの理由で送金を取り消す必要が生じた場合、ROLLBACK;というコマンドを実行する。すると、トランザクション開始以降に行われたすべての変更が取り消され、AliceとBobの口座残高は元の状態に戻る。このように、ロールバックは、不完全な操作がデータベースに記録されることを防ぎ、データの一貫性を保つ上で不可欠な機能である。この仕組みがあるおかげで、途中で問題が発生しても、データが中途半端な状態になる心配はない。

次に、デッドロックという現象について説明する。デッドロックは、複数のトランザクションが互いに相手が保持している資源(ここでは口座のデータ)の解放を待ち続け、どちらも先に進めない状態を指す。これは、ちょうど二人が一本橋で鉢合わせし、どちらも道を譲らず立ち往生しているような状況に似ている。データベースでは、データを更新する際に、他のトランザクションがそのデータを同時に変更しないように「ロック」をかけることがある。このロックが、デッドロックの原因となる場合がある。

デッドロックの発生シナリオを見てみよう。二つのセッション(データベースへの接続)が同時に動作しているとする。セッション1では、Aliceの口座から100を引く操作のためにAliceの口座をロックし、次にBobの口座に100を足そうとする。一方、セッション2では、Bobの口座から100を引く操作のためにBobの口座をロックし、次にAliceの口座に100を足そうとする。この時、もしセッション1がAliceのロックを取得した後、Bobのロックを取得しようとしたところで、すでにセッション2がBobのロックを取得していたら、セッション1はBobのロック解放を待つことになる。同時に、セッション2はBobのロックを取得した後、Aliceのロックを取得しようとしたところで、すでにセッション1がAliceのロックを取得していたら、セッション2はAliceのロック解放を待つことになる。結果として、セッション1はBobのロックを待ち、セッション2はAliceのロックを待つという、永久に解決しない相互待機状態に陥ってしまう。これがデッドロックである。現代のデータベース管理システム(DBMS)は、このようなデッドロックを自動的に検出し、どちらか一方のトランザクションを強制的に中断(アボート)させることで、この問題を解決する。中断されたトランザクションは、後でやり直すことで処理を完了できる。

最後に、ログベースリカバリという仕組みについて解説する。データベースは、システムのクラッシュや停電といった予期せぬ障害が発生しても、データを失わずに回復できる能力が求められる。これを実現するのがログベースリカバリだ。データベースは、すべての変更操作を「トランザクションログ」という特別なファイルに記録している。このログには、データを変更する前の状態(Undoログ)と、変更した後の状態(Redoログ)が詳細に記録されている。

たとえば、Charlieの口座残高に300を追加するトランザクションを開始し、UPDATE Accounts SET balance = balance + 300 WHERE name = 'Charlie';という操作を行った後、ROLLBACK;でトランザクションを取り消したとする。この一連の操作は、すべてトランザクションログに記録される。UPDATE操作がログに記録され、その変更を取り消すROLLBACK操作もまたログに記録される。この記録があるため、万が一システムがクラッシュしてメモリ上のデータが失われても、データベースはログを読み込むことで、クラッシュ直前の状態までデータを正確に復元できるのだ。具体的には、クラッシュ時にコミットされた(永続化された)トランザクションの変更はRedoログを使って再適用し、コミットされずに中断されたトランザクションの変更はUndoログを使って元に戻すことで、データベースの一貫性を回復させる。このログベースリカバリの仕組みこそが、データベースがシステム障害に強く、常に信頼性の高いデータを提供できる理由なのである。

このように、トランザクションによる原子性とロールバック、デッドロックの自動解決、そしてログベースリカバリによる永続性と回復性は、データベースが大量のデータを安全かつ確実に管理し、システム全体にわたるデータの一貫性を維持するために不可欠な技術である。これらの仕組みが連携して機能することで、私たちは安心してデータベースを利用できる。

関連コンテンツ