FE EXAM

独立性(Isolation)

並行実行される複数のトランザクションが互いに干渉しない性質。

INTERACTIVE VISUALIZATION
T1
T2
待ち
フェーズ
idle
在庫(DB上の値)
1
結果
処理中
シナリオ
ステップ1 / 7
STEP 1/7在庫1個に2人が同時注文残り在庫が1個の商品に、2人の利用者がほぼ同時に注文しました。それぞれの注文処理を T1(トランザクション1)と T2(トランザクション2)と呼びます。トランザクションとは「ひとまとまりの処理」のことです。独立性が守られていれば、片方だけが買えて、もう片方は「売り切れ」になるはずです。
T1待機T2待機DB 在庫1
解説

📌
独立性とは

T1DBデータT2互いに干渉させない

独立性(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つずつ順番に実行したのと同じ(最も強い)

分離レベル干渉の防ぎやすさ同時実行性能
低い弱い(異常が起きやすい)高い(速い)
高い強い(安全)低い(待ちが増える)

たとえば在庫管理のように間違いが許されない処理では高いレベルを、多少の表示のズレが許される閲覧画面では低いレベルを選ぶ、というように用途に応じて使い分けます。これは「安全運転(遅いが確実)」と「スピード重視(速いが危険)」のどちらを選ぶか、に似ています。

📌
読み取り異常の具体例

T1(更新側)T2(読み取り側)在庫 → 0 に書込在庫 = 0 と読むロールバック(取消)ダーティリード確定前のデータを読んでしまう異常

独立性が不十分だと、読み取り異常と呼ばれる問題が起きます。代表的な3つを覚えておきましょう。
ダーティリード:T1がまだ確定していない(=コミット前の)データをT2が読んでしまう異常。その後T1がロールバック(操作の取消)すると、T2は存在しないはずの値を使ったことになる
ファジーリード(ノンリピータブルリード):T2が同じデータを2回読んだとき、T1のコミットを挟んで値が変わってしまう異常。「さっきと値が違う!」という状況
ファントムリード:T2が件数を数えたとき、T1の挿入・削除のせいで数が変わってしまう異常。幽霊(ファントム)のように行が現れたり消えたりする

なぜこうした異常が起きるのか。それは、複数のトランザクションが同じデータに対してほぼ同時に読み書きするからです。分離レベルを上げることで、これらの異常を順番に防ぐことができます。たとえば最低レベルの READ UNCOMMITTED はダーティリードすら防げませんが、最高レベルの SERIALIZABLE は3つすべてを防ぎます。

📌
なぜ独立性が必要か

独立性なし古い値を読んで両者が処理 → 矛盾在庫 −1(二重販売)独立性ありT1が終わるまでT2は待つ → 正確在庫 0(1人のみ購入)

独立性が必要な根本的な理由は、データベースに複数の人・アプリが同時にアクセスするのが当たり前だからです。ECサイトなら何千人ものユーザーが同時に注文し、銀行システムなら何万件もの振込が並行して走ります。

もし独立性がなければ、上の図のように2つのトランザクションが同じ古い値を読んで処理してしまい、矛盾したデータが生まれます。結果として「在庫がマイナスになる」「同じ口座から二重に引き落とされる」といった致命的なデータの壊れが起きます。

独立性は、ACID(エーシッド)と呼ばれるトランザクションの4つの性質の「I」にあたります。
A(Atomicity・原子性):処理は全部成功か全部取消のどちらかにする
C(Consistency・一貫性):処理の前後でデータが矛盾しない状態を保つ
I(Isolation・独立性):複数の処理が互いに干渉しない(今回のテーマ)
D(Durability・永続性):一度確定したデータは障害があっても失われない

4つがそろって初めて、データベースは「安心して使える」ものになります。独立性はその中でも「並行処理の安全性」を担う柱です。

練習問題

🎯
基本情報技術者 練習問題

Q1.トランザクションの独立性(Isolation)の説明として最も適切なものはどれか。
A.並行して実行される複数のトランザクションが互いに干渉しない性質
B.トランザクション内の処理が全部実行されるか全くされないかになる性質
C.コミット済みの結果が障害後も保持される性質
D.実行前後でデータベースの整合性が保たれる性質
Q2.在庫1個に2人が同時注文したとき、独立性が守られていないと起こりうる現象はどれか。
A.2人とも購入に失敗する
B.在庫が増えてしまう
C.在庫1個が2人に売れてしまう(二重販売)
D.注文が永久に確定されない
Q3.分離レベル(独立性のレベル)について正しい説明はどれか。
A.分離レベルは1種類しかなく、選ぶことはできない
B.分離レベルを上げるほど干渉は防げるが、待ちが増え性能は下がりやすい
C.分離レベルを上げるほど性能が必ず向上する
D.分離レベルは原子性を調整する設定である

関連コンテンツ