【しりあらいざぶる】

Serializable とは?

最終更新:
💡 同時に処理しても、順番に実行した結果へ

並行して実行したトランザクションの結果を、ある順番で一つずつ実行した場合と同じにする分離レベルです。実際の処理をすべて一列に並べるとは限らず、競合時は再実行が必要になる場合があります。

📌 このページのポイント
同時に処理しても、直列の結果へ例:在庫1個を、AとBが購入しようとする実際には同時でもAの処理Bの処理成功した結果は…≡直列の順序と一致① Aが購入在庫は0個へ② Bは見送るA → Bの場合競合で直列化に失敗した場合トランザクション全体を再実行B → Aの順序になる場合もある
在庫があれば1個減らす処理の説明例。実際にすべてを順番に実行する、業務ロジックの誤りも防ぐ、という意味ではありません。
ひよこ ひよこ
Serializableだと、一人ずつしか処理できない?
ペンギン先生 ペンギン先生
必ずしもそうではないよ。複数のトランザクションを同時に動かしても、成功した結果が、どれかの順番で一つずつ実行した場合と一致するようにする。SQL標準の分離レベルでは最も厳格だけれど、常に全部を待たせるという意味ではないんだ。
ひよこ ひよこ
どんな矛盾を防ぐの?
ペンギン先生 ペンギン先生
ほかの未確定の変更を読むダーティリードや、読み直すと値や該当行が変わる現象を防ぐよ。さらに、個々の読み取りだけでは分かりにくい、処理群の結果がどんな直列順序とも一致しない異常も防ぐ。単に同じ行の更新を避けることより広いんだ。
ひよこ ひよこ
図の在庫の例では、どうなる?
ペンギン先生 ペンギン先生
最初の在庫が1個で、AとBがそれぞれ「在庫があれば1個減らす」を行うとしよう。Aの次にBなら、Aは購入でき、Bは在庫0を見て購入できない。その順番と同じ結果になる必要があるよ。Bが先の順番でもよく、どちらが先になるかまで指定するものではないんだ。
ひよこ ひよこ
同時に動かして、あとで矛盾が分かったら?
ペンギン先生 ペンギン先生
PostgreSQLのSerializableでは、読み書きの依存関係を監視し、直列に説明できない組み合わせを検出すると、処理を失敗させる場合があるよ。アプリはトランザクション全体を最初から再実行できるようにする。最後のSQLだけをもう一度実行すればよいとは限らないんだ。
ひよこ ひよこ
これを選べば、アプリの間違いもなくなる?
ペンギン先生 ペンギン先生
業務の条件やSQLが間違っていれば、一つずつ実行しても間違うよ。必要な処理を同じトランザクションに含め、制約や再実行時の扱いも考えよう。監視や待機、再実行には負担があるけれど、性能への影響は処理や競合の状況次第。必ず大幅に遅くなるとは言えないんだ。
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「Serializable」って出てきたら「同時に処理しても、順番に実行したのと同じ結果にする分離レベル」と思えばだいたいOK!
📖 おまけ:英語の意味
「Serializable」 = 直列化可能
💬 serialは直列。実際に全部を一つずつ動かすという意味ではなく、成功した結果を直列の順序で説明できるということだよ。

参考資料

← 用語集にもどる