【MySQL】デッドロックについてのお話
Photo by Everyday basics on Unsplash
皆さん、こんにちは
今日はデッドロックについてお話していきたいと思います。
デッドロックとは
皆さんデッドロックという言葉を聞いたことがありますでしょうか??デッドロックとは日本語に訳すと「行詰り」や「膠着状態」という意味らしいです。MySQLでは複数のプロセスが互いに相手の占有している資源の解放を待ってしまい、処理が停止してしまうこと。データベースの排他制御の不備などが原因で起こる現象です。
どういった時に発生するのか?
2つのトランザクション内でタイミングよくお互いのレコードを更新し合う時にデッドロックが発生してしまいます。
たとえば下記のようなテーブルがあったとします。
商品テーブル
id: 1, name: りんご, price: 100
id: 2, name: バナナ, price: 200
ここで2人の店員が商品の金額が間違っていることに同時に気づき修正のSQLを同時に発行しました。
店員①(トランザクション①)
begin;
UPDATE 商品テーブル SET price = 200 WHERE id = 1;
-> ここでりんごのレコードが店員①によってロックされます。解放されるのはcommitを発行した時になります。
店員②(トランザクション②)
begin;
UPDATE 商品テーブル SET price = 300 WHERE id = 2;
-> ここでバナナのレコードが店員②によってロックされます。同じく解放されるのはcommitを発行した時になります。
店員①(トランザクション①)
UPDATE 商品テーブル SET price = 300 WHERE id = 2;
-> ここでバナナのレコードは店員②によってロックされているのでその更新が完了するまでは更新できません(ロック待ち)
店員②(トランザクション②)
UPDATE 商品テーブル SET price = 200 WHERE id = 1;
-> ここでりんごのレコードは店員①によってロックされているのでその更新が完了するまでは更新できません(ロック待ち)
互いが互いにロックの解除を待っている状態をデッドロックと言います。
解決法
実装している物によって複数のユーザが共通で更新ができるようなテーブルは処理の順番を必ずIDの順番にしたりだとかそもそも共通で更新しないような設計をしてデッドロックを回避していきましょう。