mysql:15597
From: KOJIMA Takanori <KOJIMA Takanori <takanori.kojima@xxxxxxxxxx>>
Date: Thu, 26 May 2011 17:38:56 +0900
Subject: [mysql 15597] Re: SELECT MAX 〜 FOR UPDATE と INSERT でデッドロック
児島です。 > 下記の様に [A] と [B] のトランザクションを並列に実行したところ、 > > [A] BEGIN; > [B] BEGIN; > [A] SELECT @a:=MAX(id) FROM xx FOR UPDATE; > [B] SELECT @a:=MAX(id) FROM xx FOR UPDATE; /* ロック解放待ち */ > [A] INSERT INTO xx VALUES(IFNULL(@a,0) + 1); /* デッドロック? */ > > [A]のINSERTで以下の通りエラーになりました。 > ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction > > たまに発生するとかでは無くて、上の順番で実行すると百発百中で発生します。 > 上記の様な方法で連番を生成する是非はともかくとして、 > デッドロックをしてしまう理由がわかりません。 InnoDB のネクストキーロックによるものだと思います。 試しに、以下のようにトランザクション分離レベルを変更すると デッドロックはおきませんでした。 [A] SET TRANSACTION ISOLATION LEVEL READ COMMITTED; [B] SET TRANSACTION ISOLATION LEVEL READ COMMITTED; [A] BEGIN; [B] BEGIN; [A] SELECT @a:=MAX(id) FROM xx FOR UPDATE; [B] SELECT @a:=MAX(id) FROM xx FOR UPDATE; /* ロック解放待ち */ [A] INSERT INTO xx VALUES(IFNULL(@a,0) + 1); /* 成功 */
15596 2011-05-26 15:55 [<gotou1213@xxxxxxxxx] SELECT MAX 〜 FOR UPDATE と INSERT でデッドロック -> 15597 2011-05-26 17:38 ┗[KOJIMA Takanori <tak] 15598 2011-05-26 20:19 ┗[<gotou1213@xxxxxxxxx] 15599 2011-05-26 20:28 ┗[<gotou1213@xxxxxxxxx]