【入門編】 デッドロックの概念 – PostgreSQL

「ずっと待ってるのに何も進まない…」PostgreSQLのデッドロックって結局なに?

データベースを触り始めると、一度は耳にする(そして少し怖い)言葉、「デッドロック」。

エンジニアの先輩たちが「あ、これデッドロックしてるわ」なんて顔を見合わせているのを見て、「一体何が起きているんだろう?」と不安になったことはありませんか?

今日は、このデッドロックという現象を、専門用語を抜きにして、皆さんの日常にある「あるある」に例えて解説してみますね。これを読めば、もう怖くありませんよ!

—

デッドロックを「行列」に例えてみよう

想像してみてください。あなたは今、とある超人気カフェのレジに並んでいます。

  • あなた(トランザクションA):コーヒーを受け取るために、レジでお会計中。
  • 後ろの人(トランザクションB):お会計を済ませて、すぐ横にある「砂糖・ミルクコーナー」に行きたい。

ここで、こんな状況が起きたとします。

1. あなたは、お会計を終えるために「砂糖・ミルクコーナー」の場所を通らなければいけません。
2. 後ろの人は、あなたがお会計を終えるのを待っています。
3. しかし! あなたが「砂糖・ミルクコーナー」に行こうとすると、そこにはすでに後ろの人が場所を占領していて、「邪魔だよ、どいてくれ」と動いてくれません。
4. 後ろの人は、「早くあなたがレジを終わらせてくれないと、自分がそこにたどり着けない」と言って動きません。

結果、あなたも後ろの人も、お互いが「相手が動くのを待っている」状態になり、永遠に列が動きません。

これが「デッドロック」の正体です。データベースの世界では、「お互いが相手の持っているデータ(ロック)を欲しがって、永遠に譲り合わない状態」のことをこう呼ぶんです。

PostgreSQLは「凄腕の店員さん」

じゃあ、このままじゃカフェの行列は一生解消されませんよね。でも、PostgreSQLというシステムは、そんなお人好しではありません。

PostgreSQLは、まるでカフェの店員さんのように、この「膠着(こうちゃく)状態」を常に監視しています。

もし、トランザクションAとトランザクションBが「ずっと待っている」ことを検知すると、PostgreSQLは瞬時にこう判断します。

「あ、これはダメだ。このままじゃ一生終わらないから、片方を強制終了させよう!」

そうして、どちらか一方のトランザクションを「お前は一度引き下がれ!」とエラーにして追い返します。追い返された方は、「あ、ダメだったか…」と一度諦めて、後でもう一度やり直すことになります。

こうすることで、残されたもう一方は無事に処理を進めることができるんです。

なぜこんなことが起きるの?

デッドロックは、主に「複数の作業を、バラバラの順番で処理しようとした時」に起こりやすいです。

例えば、

  • あなた:Aの棚を確保してから、Bの棚を触る。
  • 相手:Bの棚を確保してから、Aの棚を触る。

このように、「掴む順番」が逆転していると、デッドロックの罠にはまりやすくなります。

どうやって対策すればいいの?

初心者の方がまず意識すべきことは、これだけです。

  • 「データの更新順序をプログラム全体で統一する」

「Aの処理をする時は、必ずA→Bの順番でロックを取る」とルールを決めておけば、そもそもデッドロックは起きにくくなります。まるで、カフェの列を「入り口から並ぶ」と決めておくようなものですね。

—

まとめ:恐れることはありません!

デッドロックは、データベースが「これ以上待っていても無駄だよ」と教えてくれる、いわば「整理のサイン」です。

もしエラーが出ても、「あ、今はちょっとタイミングが重なっちゃったんだな」と冷静に受け止めてください。多くの場合、少し時間を置いてから再試行すれば、何事もなかったかのように解決します。

データベースは、私たちが思っているよりもずっと賢く、私たちのデータを守ってくれています。失敗を恐れず、色々な処理を試してみてくださいね!

それでは、また次回の記事でお会いしましょう!

コメント

タイトルとURLをコピーしました