悲観ロックと楽観ロックの違い
悲観ロックと楽観ロックは、どちらも排他制御の代表的の方式です。
スポンサーリンク
排他制御って何?
排他制御とは、共有資源に対して同時にアクセスしても問題なく動作できる制御のことをいいます。
排他制御を行うことで共有資源のデータに不整合が起きることを防ぎます。
例えば、ショッピングサイトがあるとします。ショッピングサイトの商品(共有資源)を同時に購入した時、排他制御が行われていないとどうなるのでしょうか。
① 共有資源の商品を同時に購入
共有資源の同じ商品をタイミング的に2人同時に購入する事は、そこまで発生する事ではないかもしれません。ただ人気のショッピングサイトであればあるほど、その可能性は高くなります。
② 在庫を確認する
まず購入した商品の在庫が残っているか確認します。今回の例では在庫は残り"10"とします。
③ 在庫を減らす
次に在庫を減らします。在庫の残りは"10"なので、1つ減らして"9"にします。
スポンサーリンク
ここで問題になるのは、排他制御をしていない為、同時に操作した両方が在庫を"10"から"1"減らした"9"で在庫数を更新してしまうのです。そのため在庫数が本来とは違う、間違ったデータになってしまいました。
このような問題を防ぐために排他制御があり、データの整合性を保つことが目的です。
悲観ロックって何?
悲観ロックとは、排他制御の代表的な方式の一つで、同じデータを他者が頻繁に更新するという悲観的な考え方の排他制御です。具体的には、更新対象データを取得時にロックして他者が操作できないようにする方式。
それでは悲観ロックの動きを具体的に紹介していきます。
① 共有資源の商品を同時に購入
ショッピングサイトに対して「Aさん」と「Bさん」が同時に同じ商品(共有資源)を購入します。
② 共有資源に対してデータを読み取りロックする
購入可能であるか確認するために「在庫テーブル」から対象商品の「在庫数」を取得します。まずは「Aさん」がデータを取得します。この時、対象商品のデータをロックします。
③ 共有資源はロックされているので、読み取りできない
次に「Bさん」も「在庫テーブル」から対象商品の「在庫数」を取得しようとするが、対象商品のデータはロックされているので、読み取る事ができません。
スポンサーリンク
そのため、ロックが解除されるまで待機します。
④ 共有資源を更新し、ロックを解除する
在庫を取得してきた10から1減らして「Aさん」の購入を確定します。「在庫テーブル」の「在庫数」は"9"です。更新が完了したらロックを解除します。(コミット または ロールバックのタイミングで解除)
⑤ 再度、共有資源に対してデータを読み取りロックする
対象商品のデータのロックが解除されたので、「Bさん」がデータを取得します。この時、対象商品のデータをロックします。
⑥ 共有資源を更新し、ロックを解除する
在庫を取得してきた9から1減らして「Bさん」の購入を確定します。「在庫テーブル」の「在庫数」は"8"です。更新が完了したらロックを解除します。(コミット または ロールバックのタイミングで解除)
スポンサーリンク
楽観ロックって何?
楽観ロックとは、排他制御の代表的な方式の一つで、そもそも「同時アクセスはあまり起きない」という楽観的な考え方の排他制御です。データ自体をロックすることはせず、更新対象のデータが更新前と同じであるかを確認してから更新することで、データの整合性を保つ排他制御。
それでは楽観ロックの動きを具体的に紹介していきます。
① 共有資源の会員サイトを同時に閲覧
共有資源である顧客情報が掲載されている会員サイトを同時に閲覧します。(同じ顧客情報)
ここでポイントなのは「顧客テーブル」にバージョンが付与されているところです。
② 共有資源の顧客情報を更新する
まず右側の女性が顧客情報の顧客名を更新します。
まず右側の女性が顧客情報を更新します。この時、「顧客テーブル」のバージョンがカウントアップされ「2」に更新されます。
次に左側の男性がやや遅れて顧客情報を更新します。
しかしデータ取得時と更新時の「顧客テーブル」のバージョンが異なる(カウントが「2」になっている)為、楽観ロックエラーになり、更新されません。
このようにデータ自体をロックする悲観ロックとは違い、楽観ロックは同時アクセスが発生した場合、後から更新した方をエラーにすることでデータの整合性を保つ方式です。