こんにちは!パイプドビッツ 福岡支店の古場(こば)です。
最近わくわくしたことはソフトバンクホークス 東浜投手のノーヒットノーラン試合でしょうか…
帰りにヒーローインタビューを見ながらSNS上で友人と盛り上がっておりました(笑)
今年は優勝してほしいなと思いながら毎日結果を見ています!
ってそんな私の個人的なニュースがどうでもよくて!
このブログを見てくださっている皆様、1つ質問です。
スパイラルを触っていて「デッドロックの可能性」のエラーに出会ったことはありますか?
(※そんなに頻繁に出会うエラーではない)
私は何度かこのエラーにあったことがあるのですが、
このエラーが起きるのか、雰囲気では分かりながら根本がイマイチわからず…
お客様に案内することもある手前、自分なり(というよりも自分が分かるように)に調べてみました!
デッドロックとは?
デッドロックで調べてみると、言葉の意味はこのように書いてありました。
「デッドロックとは、互いに他のプログラムの結果待ちとなり、待機状態に入ったまま動かなくなる現象のこと」
うーーん??????
次の動作ができない、ということは分かるけれど、具体的にどんな状況で発生するのかが私の頭ではイマイチ理解できず。
なんかないの!?と探していると、分かりやすいサイトを見つけました!
デッドロックとは – ITをわかりやすく解説
デッドロック (deadlock)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
さくっと理解したい!という方はこちらがおすすめ。
ここからURLを参考にスパイラルに置き換えて、古場が独り言を言っているので、
しゃーないな、読んでやるか!という時間に余裕がある方は読んでみてください(笑)
THE・文系人間が分かるように書いているので、きっと分かりやすくなってると思います。(自己満足)
デッドロックはなぜ起きる?
デッドロックは複数のトランザクションDB(以下:TRDB)があり、それぞれ複数のDBに更新・もしくは登録更新のアクションの設定が複数あると起こりやすいです。
これはデータ更新をする際にDBがロックされ、データが入ってこれない状態になるが原因なのだそう。
そこで古場は新たな疑問にぶつかります。
「DBのロック」ってなに??
なんかまた新しいのが出てきたんですけど??
文字だけでは頭がこんがらがる一方なので…ひとまずDBを部屋と置き換えて、イメージ図にして考えてみました。
TRDBからアクション先データの更新イメージ
TRDBからDBにデータが入り更新を行う前、更新作業中にデータが入ってこないように作業前にDBをロックします。
これが「DBのロック」です。
作業の間はデータが入ってこないので、影響なく更新が可能になります。
そして更新が終わった後はロックが解除されるので、次のデータが入ってくることができます。
では複数のDBに更新アクションがある場合はどうなる??
TRDBで複数の更新アクションがある場合
複数のDBに対してアクションを行う場合、「最初はりんごDBにアクション、次にみかんDBへ」というように、アクションする順序を決め、順序通りに動作します。
1回目の更新アクションは、アクションが1つだけのときと同じで、DBにロックをかけて更新作業をします。
2回目以降の更新アクションは、まず次のアクション先DBの様子を確認。
その後、次のDBのロックがかかっていなければ作業完了したDBのロックを解除し、次のDBへ移動・次のアクション動作を行います。
「次のアクション先のDBにロックがかかってたらどうすんの?」というところですが、
その場合はロックが外れるまで、作業が完了したDBで「待機状態」となります。
出た!よく分かんない「待機状態」!
次のDBがロックされていたら、次の動きはできない(今の作業の完了ができない)ため、ロックをしたまま待機状態になります。
さらに作業が完了していても新しい更新データは入ってこれないため、作業完了したDBで新しいアクションの動きもすることができません。
この「何もできない状態」が2つあり、お互いのアクションが何もできなくなっている状態を「デッドロック」といいます。
なんとなく原理は分かってきた…!
デッドロックになるデータの入り方
どういう状態になればデッドロックになるか、ということは分かってきたので、
イメージしやすいようにTRDBを2つ並べて、デッドロックになるデータの流れを図にしてみました。
イメージのTRDB例
【TRDB1】
アクション順1:りんごDBのデータを更新
アクション順2:みかんDBのデータを更新
【TRDB2】
アクション順1:みかんDBのデータを更新
アクション順2:りんごDBのデータを更新
※TRDBに同時にデータが入ってきて、TRDB1のアクション順1の動きがTRDB2より先に終わったとする。
まずアクション順1はイメージするとこんな感じ。
TRDB1からアクション順①の順番通りにりんごDBに入ったデータは、無事に更新アクション処理が終わりました。そこで次のアクション先であるみかんDBの様子を見ると、まだ更新作業が終わってない様子。
なのでりんごDBをロックしたまま、みかんDBの更新処理が終わるのを待ちます。
その後、TRDB2からのデータがみかんDBでのアクション処理が終わりました。りんごDBの様子を見るとロックがかかっています。
それならデータ処理が終わるまで待っていようと、みかんDB側もロックしたまま、りんごDBのロックが解除されるのを待ちます。
ということで、どちらも待ってしまう状態となり、お互いロックが解除されるまで動けません。
これがデッドロックの状態です。
デッドロック状態になるすべてがこの動きということではないですが、このようにデータの動きが止まってしまう可能性があり、
データの動きが止まる=システム自体も止まってしまう恐れがあります。
なので、スパイラルではデッドロックになりそうなアクション設定がされると、
「アクションの発動する順番により、デッドロックが発生する可能性があるため設定できません」とエラー文を出して、
デッドロックになりそうなアクション設定をさせないようにしています。
デッドロック!理解できた!(はず)
デッドロックのエラーを避けるには?
デッドロックのエラーが出たら、もう設定はできないの・・・?と諦めるのはまだ早い!
アクション発動の順序を変えると回避できるかもしれません。
スパイラルで実際にデッドロックエラーを回避してみます。
まず1つめのTRDBのアクション設定。
そして2つめのTRDBのアクション設定で画像のように設定しようとしてみます。
これで確定ボタンを押すと、デッドロックのエラーが出ます。
このとおり…(泣)。
1つめに設定したTRDBのアクションの順番が邪魔してデッドロックが起きるかもだそうです。
なので、2つめのTRDBのアクションの順番を最初に設定したTRDBのアクションの順番と同じにします。
これでデッドロックのエラーなくTRDBのアクション設定ができました!
TRDBのアクション設定のヒント
・複数のTRDBで複数のDBに更新アクションをする場合は、アクションするDBの順序を揃える。
(2つのTRDBを使って、それぞれが会員DB・マスタDBに更新アクションをする場合、
どちらも会員DB(更新)→マスタDB(更新)の順番にする)
・登録、削除のアクションがある場合でも、更新するDBのアクションの順序は揃える。
もしTRDBのデッドロックでお困りの場合は、ぜひ順序を変えて試してみてください!
ここまでの長文を最後まで読んでくださった方、ありがとうございます!
ほんとに感謝です…!
デッドロックのエラーについてはサポートサイトにも記事がないので、お役に立てると幸いです!
もし、「ここなんか違うのでは…?」というのがあればこっそり教えていただけるとありがたいです…