並行実行される複数のトランザクションが互いに干渉しない性質。
独立性(Isolation)とは、同時に走る複数のトランザクション(=ひとまとまりの処理)が、互いに干渉しない性質のことです。あるトランザクションの「処理の途中の状態」が、別のトランザクションから見えたり邪魔されたりしないように守られます。
身近な例で考えると、銀行ATMの順番待ちが分かりやすいです。前の人が記帳・引き出しを終えるまで、次の人は同じ口座を操作できません。もし途中で割り込めたら、残高がぐちゃぐちゃになってしまいます。独立性とは「1人ずつ順番に使ったのと同じ正しい結果」を保証する仕組みです。
上のツールで▶ボタンを押すと、在庫1個の商品に2人が同時注文したとき、独立性が守られている場合と守られていない場合でどう結果が変わるかを確認できます。
独立性は、おもに ロック(=データを一時的に占有して他者の操作を制限する仕組み) によって実現されます。あるトランザクションがデータを使っている間は鍵をかけ、終わったら鍵を外す、というイメージです。
上のツールの「独立性あり」シナリオでは、次の流れで干渉を防いでいます。
・① T1がデータを占有:T1 が在庫を読んだ時点で、そのデータをロックする
・② T2は待たされる:T2 はロックが外れるまで処理を待つ(割り込めない)
・③ T1の完了後にT2が再開:T1 がコミットしてロックを解放したら、T2 が最新の値を読んで処理する
逆に「独立性なし」シナリオでは、T1 が書き込む前に T2 も同じ古い在庫値(=1)を読んでしまいます。その結果、両方が「最後の1個を買える」と勘違いし、在庫が −1 になる二重販売という異常が起きます。途中状態を他者に見せないことが、いかに大切かが分かります。
独立性は「全か無か」ではなく、分離レベル(独立性をどれだけ厳しくするかの段階)を選んで調整できます。レベルが高いほど干渉を強く防げますが、その分ロックや待ちが増えて処理の同時実行性能が下がります。安全性と速さのバランスを取って選びます。
分離レベルは、低いものから高いものへ、おもに次の4段階があります。
・READ UNCOMMITTED:未確定の途中データまで読めてしまう(最も弱い)
・READ COMMITTED:確定済みのデータだけ読む
・REPEATABLE READ:同じデータを何度読んでも値が変わらない
・SERIALIZABLE:完全に1つずつ順番に実行したのと同じ(最も強い)
| 分離レベル | 干渉の防ぎやすさ | 同時実行性能 |
|---|---|---|
| 低い | 弱い(異常が起きやすい) | 高い(速い) |
| 高い | 強い(安全) | 低い(待ちが増える) |
たとえば在庫管理のように間違いが許されない処理では高いレベルを、多少の表示のズレが許される閲覧画面では低いレベルを選ぶ、というように用途に応じて使い分けます。これは「安全運転(遅いが確実)」と「スピード重視(速いが危険)」のどちらを選ぶか、に似ています。
独立性が不十分だと、読み取り異常と呼ばれる問題が起きます。代表的な3つを覚えておきましょう。
・ダーティリード:T1がまだ確定していない(=コミット前の)データをT2が読んでしまう異常。その後T1がロールバック(操作の取消)すると、T2は存在しないはずの値を使ったことになる
・ファジーリード(ノンリピータブルリード):T2が同じデータを2回読んだとき、T1のコミットを挟んで値が変わってしまう異常。「さっきと値が違う!」という状況
・ファントムリード:T2が件数を数えたとき、T1の挿入・削除のせいで数が変わってしまう異常。幽霊(ファントム)のように行が現れたり消えたりする
なぜこうした異常が起きるのか。それは、複数のトランザクションが同じデータに対してほぼ同時に読み書きするからです。分離レベルを上げることで、これらの異常を順番に防ぐことができます。たとえば最低レベルの READ UNCOMMITTED はダーティリードすら防げませんが、最高レベルの SERIALIZABLE は3つすべてを防ぎます。
独立性が必要な根本的な理由は、データベースに複数の人・アプリが同時にアクセスするのが当たり前だからです。ECサイトなら何千人ものユーザーが同時に注文し、銀行システムなら何万件もの振込が並行して走ります。
もし独立性がなければ、上の図のように2つのトランザクションが同じ古い値を読んで処理してしまい、矛盾したデータが生まれます。結果として「在庫がマイナスになる」「同じ口座から二重に引き落とされる」といった致命的なデータの壊れが起きます。
独立性は、ACID(エーシッド)と呼ばれるトランザクションの4つの性質の「I」にあたります。
・A(Atomicity・原子性):処理は全部成功か全部取消のどちらかにする
・C(Consistency・一貫性):処理の前後でデータが矛盾しない状態を保つ
・I(Isolation・独立性):複数の処理が互いに干渉しない(今回のテーマ)
・D(Durability・永続性):一度確定したデータは障害があっても失われない
4つがそろって初めて、データベースは「安心して使える」ものになります。独立性はその中でも「並行処理の安全性」を担う柱です。