2017-03-31 9 views
0

innodDBは一貫性のあるメカニズムノンブロッキング read、 を使用するので、すべてのトランザクションは独自のスナップショットで動作します。MySql InnoDB反復可能な読み取りロックの予期しない動作

それは読み取り一貫性は、それがアクセスするテーブル上のすべてのロックを設定するので、他のセッションは、読取り一貫性があると同時に、それらのテーブルを自由に変更できますしない公式documentation

でも語られていますテーブル上で実行されます。

しかし、古典的な '読み取り/更新' デッドロックが表示されたら、私が予期せず行動に直面:

分離レベルは REPEATABLE READ

(もを犯し READで再現された)
  1. トランザクション1読み取り行(NOT共有モードでロック)。

  2. トランザクション2(共有モードNOTロック)同じ行を読み出します。 次に

  3. トランザクション1はこの行を更新しようとします。

  4. トランザクション2もこの行を更新しようとします。 ---------------- 2017年3月31日16時07:最後のステップの後

は、InnoDBはデッドロック(以下最新DETECTEDデッドロックがある)を検出します。 03 0x1f58 ***(1)TRANSACTION: トランザクション413412、アクティブ20秒の開始インデックスの読み取り 使用中のmysqlテーブル1、ロックされた1 ロック・ロック9ヒープ・サイズ1136,6ロック・ロック(s) 、ログエントリの取り消し3 MySQLスレッドID 33、OSスレッドハンドル8148、クエリID 102005ローカルホスト127.0.0.1ルート更新

/* update Order */ update `Order` set ... <fields to update> 

*** (1) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 2151 page no 709 n bits 88 index PRIMARY of table `ooapp2`.`order` trx id 413412 lock_mode X locks rec but not gap waiting 
Record lock, heap no 3 PHYSICAL RECORD: n_fields 54; compact format; info bits 0 

*** (2) TRANSACTION: 
TRANSACTION 413413, ACTIVE 11 sec starting index read 
mysql tables in use 1, locked 1 
9 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 3 
MySQL thread id 28, OS thread handle 8024, query id 102008 localhost 127.0.0.1 root updating 

/* update Order */ update `Order` set ...<fields to update> 

*** (2) **HOLDS THE LOCK(S):** 
RECORD LOCKS space id 2151 page no 709 n bits 88 index PRIMARY of table `ooapp2`.`order` trx id 413413 lock mode S locks rec but not gap 
Record lock, heap no 3 PHYSICAL RECORD: n_fields 54; compact format; info bits 0 

*** (2) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 2151 page no 709 n bits 88 index PRIMARY of table `ooapp2`.`order` trx id 413413 lock_mode X locks rec but not gap waiting 
Record lock, heap no 3 PHYSICAL RECORD: n_fields 54; compact format; info bits 0 

*** WE ROLL BACK TRANSACTION (2) 
0123トランザクション2

がLOCK(S)を保持し、なぜ私は、何が起こる、理解できない

ので、InnoDBはそれにもかかわらず、これがない スナップショットとセットS-ロックでの一貫した読み取りを使用しない場合公式マニュアルに書かれている事実に対応していない。

答えて

1

しないでください。行を更新しているのにその値が必要な場合は、SELECT ... FOR UPDATE;を使用してください。ちょうどそれをして、約tx_isolationを忘れてください。通常、デッドロックは遅延になります。(innodb_lock_wait_timeoutを参照してください。デフォルトでは50秒超過です)

デッドロックが発生した場合は、トランザクション全体を再実行してください。デッドロックは、あなたがそれらを避けようとしてどれほど苦労しても起こります。

関連する問題