データベースのダーティリードとは?SQLトランザクションの仕組みを初心者向けに徹底図解
生徒
「データベースを勉強していると『トランザクション』とか『ダーティリード』っていう難しい言葉が出てきて混乱しています。パソコン初心者でもわかりますか?」
先生
「言葉は難しそうですが、仕組みはシンプルですよ。データベースは、たくさんの人が同時にデータを書き換えようとしたときに混乱しないよう、ルールを決めているんです。」
生徒
「そのルールを破ってしまうと、ダーティリードという問題が起きるんですね?」
先生
「その通りです。今回は、銀行の振り込みやネットショッピングの在庫管理を例にして、何が問題なのかを順番に見ていきましょう。」
1. SQLとは何か?
SQLは、データベースと呼ばれる「大量のデータを整理して保存する箱」に対して指示を出すための言語です。例えば、会員名簿の中から特定の人を探したり、新しい人を追加したりするときに使います。銀行の残高や、お店の商品の数も、このデータベースという箱の中でSQLを使って管理されています。私たちは普段、スマートフォンやパソコンを使って何かを操作していますが、その裏側ではSQLという魔法の言葉が動いてデータを操作しているのです。
エンジニアの必須スキル「SQL」を、 図解と豊富な練習問題でゼロから体系的に学びたい人へ。 MySQLやPostgreSQLなど、各種データベースに対応した不朽の入門書です。
SQL 第2版 ゼロからはじめるデータベース操作をAmazonで見る※ Amazon広告リンク
2. トランザクションとは「ひとまとまりの作業」
データベースを学ぶ上で、避けて通れないのがトランザクションという概念です。これは、複数の処理を「全部成功するか、全部失敗するか」のどちらか一方で管理する仕組みのことです。
例えば、あなたが友だちに1,000円を振り込む場面を想像してください。このとき、銀行のデータでは次の2つの作業が行われます。
- あなたの口座から1,000円を引く
- 友だちの口座に1,000円を足す
もし「1」だけ終わったところでシステムが止まってしまったらどうなるでしょうか?あなたのお金は消えて、友だちには届かないという最悪の結果になります。これを防ぐために、2つの作業をセットにして、どちらかが失敗したらすべてを「なかったこと」にする仕組み、それがトランザクションです。
確定させることを「コミット」、やり直すことを「ロールバック」と呼びます。この「確定前」の状態が、今回解説するダーティリードに深く関わってきます。
3. ダーティリード(Dirty Read)の正体
ダーティリードとは、一言で言うと「他の人がまだ確定させていない(書き換え中の)怪しいデータを読み取ってしまうこと」を指します。「ダーティ」は「汚れた、不潔な」という意味ですが、ここでは「まだ正式に認められていない、不正確な」という意味で使われます。
具体的に、ネットショップの在庫管理を例に考えてみましょう。現在、ある商品の在庫が「10個」あるとします。
id | product_name | stock | category
---+--------------+-------+----------
1 | スニーカー | 10 | 靴
2 | サンダル | 5 | 靴
3 | Tシャツ | 20 | 衣類
4 | キャップ | 15 | 帽子
5 | リュック | 8 | カバン
ここで、Aさんがスニーカーを1個購入しようとしています。システムは在庫を「9個」に書き換えますが、まだ支払いが終わっていないので「確定(コミット)」はしていません。SQLでは以下のような命令が動いています。
-- 作業A(Aさんの購入処理開始)
START TRANSACTION;
UPDATE products SET stock = 9 WHERE id = 1;
-- まだ確定(COMMIT)していません!
この「確定していない瞬間」に、Bさんがショップのページを開いて、在庫数を確認しました。Bさんの画面には「在庫:9個」と表示されます。この「まだ確定していない9個という数字を見てしまうこと」がダーティリードです。
しかし、ここで問題が起きます。Aさんが支払いに失敗し、購入をキャンセルしました。システムは在庫を元の「10個」に戻します(ロールバック)。
-- 作業A(やっぱりキャンセル!)
ROLLBACK;
その結果、在庫データは以下のようになります。
id | product_name | stock | category
---+--------------+-------+----------
1 | スニーカー | 10 | 靴
2 | サンダル | 5 | 靴
3 | Tシャツ | 20 | 衣類
4 | キャップ | 15 | 帽子
5 | リュック | 8 | カバン
Bさんは「在庫は9個だ」と信じ込んでいますが、実際には10個あります。もしこれが、最後の一つを争うような場面だったらどうでしょう?Bさんは「残り1個だ!急いで買わなきゃ!」と思ったのに、実際にはまだ在庫が残っていたり、逆に存在しないはずの数字を見てしまったりすることで、システムに矛盾が生じてしまうのです。
4. 同時実行制御が必要な理由
データベースには、たくさんの人が同時にアクセスします。1人だけで使っているなら問題ありませんが、世界中の何万人という人が同時にデータを読み書きすると、こうした「データの矛盾」が頻繁に起きてしまいます。これを防ぐための技術を同時実行制御(並行性制御)と呼びます。
同時実行制御には、いくつかのレベル(隔離レベル)が用意されています。ダーティリードを絶対に許さない設定にすることもできれば、多少の誤差は許してスピードを優先する設定にすることもできます。初心者のうちは、「みんなで一つのデータをいじるときは、誰かが作業を終えるまで待ってもらう必要がある」と覚えておけば十分です。
5. 他にもある!トランザクションの問題点
ダーティリード以外にも、複数の人が同時にデータを触ることで起きる問題があります。代表的なものを2つ紹介します。
アンリピータブルリード(読み取りの不整合)
自分が1回目の確認をした後に、別の誰かがデータを確定させてしまったため、2回目の確認をしたら数値が変わってしまっている現象です。さっき見たときと違う!という驚きが発生します。
ファントムリード(幻のデータ)
さっきまで無かったはずのデータが、誰かの追加によって突然現れる現象です。まるで「幽霊(ファントム)」のようにデータが増えて見えるため、こう呼ばれます。
これらの問題を防ぐために、SQLでは「作業の独立性」を保つルールが厳格に決められています。例えば、以下のSQLのように特定の条件でデータを取得する際、他の人が邪魔をできないように鍵(ロック)をかけることもあります。
-- データを読み取るときに、他の人が書き換えられないように予約する
SELECT * FROM products WHERE category = '靴' FOR UPDATE;
この「FOR UPDATE」という魔法の言葉をつけると、「今このデータを私がチェックしているから、他の人は確定するまで待っててね!」とデータベースにお願いすることができます。
6. データベースエンジニアへの第一歩
「SQLはただの表計算ソフトのようなもの」と思っていた方も、こうした「同時実行」の仕組みを知ると、データベースがいかに緻密に設計されているかがわかるはずです。プログラミングの経験がなくても、この「データの整合性を保つ」という考え方は、日常の事務作業や整理整頓にも通じる非常に大切なスキルです。
まずは、自分が使っているアプリやサイトの裏側で、誰かが「今、トランザクションを開始したぞ!」「ここで確定(コミット)したんだな」と想像してみることから始めてみてください。それが、優秀なエンジニアやデータ活用への近道になります。