[前][次][番号順一覧][スレッド一覧]

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]