there is a time for everything

現役SIerが技術や育児情報を紹介するブログです。

楽観的ロック、悲観的ロック

今日は真面目な話

世の中のデータは膨大です。
そのデータ管理の失敗によっては、大きく世の中に影響を与えてしまうものもたくさんあります。そんな、世界のデータ量はぐんぐんと増え続けており、2020年にはなんと44ZB(ゼタバイト)にまで増加する見立てだそうです。

まず、ゼタバイトってなに?

となりますよね。GB(ギガバイト)でしたら、まだ身近でしょうか。44ZBは44兆GBに相当するそうです。何じゃそりゃ。

データの取り合い

では今日の本題ですが、世の中のITサービスはクライアントとサーバと呼ばれる構成が大半を占めています。クライアントがご覧になっているようにPCやスマホに該当し、サーバと呼ばれるデータの貯蔵庫からサイトの情報を汲み取って皆様の目に見えているわけです。

で、そのデータの取り合いを管理する方法として楽観的ロック、悲観的ロックと呼ばれる手法があります。

例えると

データの取り合いの管理方は、店頭販売の人気ソフトクリーム店で考えてみましょう。

<悲観的ロック>
大人気店にも関わらず、レジはなんと一つです。
当然、ソフトクリームが食べたくて押し寄せてきた人々は長い行列を作ることになります。
これが、データ取得のキューと考えてもらったら良いです。

前の人の注文が終わらなければ、次の人が注文することは絶対にできません。そのかわり、在庫状況を見誤ることは決してありません。注文される際に、「もう在庫ないよ!」と必ず気づくことができます。
リアルタイムでデータ状況を把握していることになります。ちょっと強引か

ある意味、悲観的ロックにはデータの取り合いは発生しないことになります。

<楽観的ロック>
大人気店なので、レジは2つあります。
ソフトクリーム大好きな人々は2つのレジに分散して行列を作ります。

注文の待ち行列は短くなりました。ただ、注文時に在庫状況が正しく把握できなくなってしまいました。

Aのレジで「抹茶味3つ!」と注文されて在庫がなくなったにも関わらず、直後にBのレジで「抹茶味2つ!!」なんてことが起きてしまい、Bのレジで注文した人には「すみません、ご注文頂いた抹茶味は在庫切れでして。。。」と伝えることになります。

UXの違いは?

では、楽観的ロックと悲観的ロックでは、ユーザにどのような変化が現れるのか。ソフトクリーム注文システムなるものが存在するとしましょう。

<悲観的ロック>
ソフトクリーム注文画面にアクセスします。
そして、抹茶味を一つ注文。
在庫が足りていたので、問題なく注文できます。

<楽観的ロック>
ソフトクリーム注文画面にアクセスします。
そして、抹茶味を注文。
が、「抹茶味は売り切れです!再度、注文画面に戻って商品を選択してください。」

システム的には何が起きている?

対して違いがわからないと思うので、もう少し掘り下げてみましょう。
括弧書きでシステムの状態を記述してみます。

<悲観的ロック>
ソフトクリーム注文画面にアクセスします。
(お、お客さんやわ。ソフトクリームの在庫データをロックや!)

そして、抹茶味を一つ注文。
(抹茶の在庫からマイナス1やな。)

在庫が足りていたので、問題なく注文できます。
(よし、注文トランザクション正常終了や。ロック解除、と。)

<楽観的ロック>
ソフトクリーム注文画面にアクセスします。
(お、お客さんやわ。いらっしゃい~)

そして、抹茶味を注文。
(また抹茶味か、在庫データを確認やな。あっ、もうないわ!)

が、「抹茶味は売り切れです!再度、注文画面に戻って商品を選択してください。」
(すまんな。先約があったわ。やり直してや。)

どっちがいいの?

かなり稚拙な例えでしたが、在庫データの確認タイミングが異なることに気付いたでしょうか。

悲観的ロックでは、かなり厳重なデータロックと言えます。
データを参照してから更新するまで、他者のアクセスを受け付けません。データが自分以外の誰かに、予期せぬ変更を加えられるかもしれない、というとても悲観的な捉え方から、「悲観的ロック」と呼ばれています。

楽観的ロックでは、データ参照時は何も行われず、データ更新時に在庫データを参照しています。これはつまり、データ管理的には他者のデータ更新を受け入れていることになります。
管理できるに越したことはないが、複数人のアクセスが考えられるのだから、誰か更新しているかもしれない、という考えから「楽観的ロック」と呼ばれています。

じゃあ、どっちがいいの?という話ですが、システムの目的に依ります。

どんな違いが?

開発時には大きな違いが発生します。
どちらがいい、ということではありませんが、悲観的ロックではRDBMSに頼る形で対応することとなり、楽観的ロックではアプリケーションの作り込みが必要になります。

これだけ聞くと前者が楽ちんに感じられますが、例えばAmazonなどの大規模ECサイトでは悲観的ロックなんてしてたら業務になりません。ですから、データをアプリケーション的に擬似ロックするかのように「カートに入れる」というアクションが用意されているのだと思います。それでもデータの取り合いは発生しますけどね。

どっちが流行り?

これは個人的な経験に基づくのであまり信用して欲しくないのですが、楽観的ロックがほとんどでした。WEB系の仕事で悲観的ロックは取り扱ったことがありません。もちろん、使ってはいけないということではありませんが、私は見たことないですね。

おまけ

若手育成にも関わるお年頃ですので、ちょっと説明しやすくまとめてみたつもりです。でもちょっと、強引なまとめ方になってしまいました。

トランザクション管理ができないと大規模かつ堅牢なシステム開発はできないので、年次の低い頃から身に付けて頂きたいです。いつも少しだけ、自分のスキルエリアを超えたところに手を出す癖を付けると、指数関数的に成長できて本人も楽しいんじゃないかな、と思います。

SEをご存知ない方、読んで頂いてありがとうございます。
結構、込み入った話で楽しくなかったかもしれませんが、日々こんな細かいことばかり黙々と考えるのがSEです。日頃からこんなに細かいと辟易されるかもしれませんが、ちょっとくらいは多めに見てあげてくださいね。

ではまた。