updateとinsertをアトミックに行うよう考慮する
何かを登録するとき、すでに存在するデータがあれば上書きする必要があるので、まずupdateを試みる。
失敗したら、まだ存在していないので、insertする。
・・・という2つの処理の組み合わせを行う設計がある。
この場合、途中で邪魔が入らない=アトミックな処理であることを保証する必要がある。
そうしないと不正な状態になる場合がある。
不正な状態とは
たとえばAとBがほぼ同時(Aが少し早い)に、同じ情報で新規会員登録をした場合。
2つの処理がアトミックでない場合、下記順番で処理が行われる場合がある。
A update 失敗
B update 失敗
A update失敗を受けてのinsert 成功
B update失敗を受けてのinsert 失敗★NG
★の失敗は、B update失敗を受けてのinsertなのに失敗するという、不正な状態となる。
アトミックにすると
下記のようになる。
A update 失敗
A update失敗を受けてのinsert 成功
B update 成功★OK
アトミックにするにはSQL文を関数化する
---
アトミックとは、原子的、非可分であること。「アトミックな操作」であるというとき、ある操作を行なうときに他者がその操作に割り込めないことを指す。
不可分操作は、以下の2つの条件を満たさなければならない。
- 全操作が完了するまで、他のプロセスはその途中の状態を観測できない。
- 一部操作が失敗したら組合せ全体が失敗し、システムの状態は不可分操作を行う前の状態に戻る。
システムの他の部分から見て、操作の組合せが一度に成功したか失敗したように見える。途中の状態にアクセスすることはできない。このため不可分操作あるいはアトミック操作(= 原子操作)と呼ぶのである。
マルチプロセッサでなくとも、この実装は重要である。制御の流れが変更される可能性がある限り、不可分性がなければシステムが不正な状態になってしまう可能性がある。