8

MySQL+InnoDB で、単一のテーブルと、"SELECT ... FOR UPDATE" を実行する 2 つのスレッドがあるとします。両方の SELECT ステートメントが複数の行を選択することになるとします。たとえば、両方とも行 R42 と R99 を選択することになります。これがデッドロックになる可能性はありますか?

私はこの状況を考えています。最初のスレッドは R42 をロックしてから R99 をロックしようとし、2 番目のスレッドは R99 をロックしてから R42 をロックしようとします。運が悪いと、2 つのスレッドがデッドロックしてしまいます。

「デッドロック」のMySQL用語集を読みました

トランザクションが (UPDATE または SELECT ... FOR UPDATE などのステートメントを使用して) 複数のテーブルの行をロックすると、デッドロックが発生する可能性がありますが、その順序は逆です。...

デッドロックの可能性を減らすには、 ... SELECT ... FOR UPDATE および UPDATE ... WHERE ステートメントで使用される列にインデックスを作成します。

これは、私の状況 (単一のテーブル) ではデッドロックしないことを示唆しています。これは、MySQL が主キーの順序で行を自動的にロックしようとするためかもしれませんが、確実にしたいのですが、何が起こっているかを正確に教えてくれるドキュメント。

4

1 に答える 1

3

MySQLのドキュメントから

InnoDB uses automatic row-level locking. You can get deadlocks even in the case of 
transactions that just insert or delete a single row. That is because these operations    
are not really “atomic”; they automatically set locks on the (possibly several) index 
records of the row inserted or deleted.

http://dev.mysql.com/doc/refman/5.1/en/innodb-deadlocks.html

したがって、通常、デッドロックは致命的ではありません。再試行するか、適切なインデックスを追加して、スキャンされる行が少なくなり、ロックされる行が少なくなるようにする必要があります。

于 2012-06-13T03:48:00.753 に答える