web-dev-qa-db-ja.com

2つのmySQLクエリの両方が同じ行を同時にロックしようとするとどうなりますか?

したがって、これは厳密には私の強い訴訟ではありませんが、状況についての私の基本的な理解は次のとおりです。

同じアプリケーションの2つのスレッドが両方とも同時に同じクエリを実行しようとすると、mySQLでデッドロックが発生します。デッドロックを防ぐ方法は、書き込む前にテーブル(または行)をロックすることです。しかし、lockingリクエストが同時に発生した場合はどうなりますか?

例えばあなたは次のようなテーブルを持っています:

#my_table
---------------
| key | value |
---------------
|  1  |  foo  |
---------------
|  2  |  bar  |
---------------

次に、アプリケーションで次のようなクエリを記述します

LOCK TABLES my_table WRITE;
UPDATE my_table SET value = Rand() WHERE key = 2;
UNLOCK TABLES;

そして奇跡的に、このクエリの2つのインスタンスがまったく同じミリ秒(ナノ秒?)で起動します。それが重要であれば、それはInnoDBテーブルです。

3
Matt Korostoff

これはデッドロックではありません。

1つのトランザクションは単純にブロックされ、ロックの取得を待機します。他のトランザクションが続行されます。他のトランザクションが完了すると、commitまたはrollbackによって、最初のトランザクションが続行されます。

デッドロックは、トランザクションがオブジェクトAのロックを取得し、別のトランザクションが既にオブジェクトBのロックを取得してオブジェクトAのロックを取得しようとしているときに、オブジェクトBのロックを取得しようとすると発生します。その後、トランザクションはブロックされ、互いに待機します。これがデッドロックの定義です。2つのトランザクションは、他のトランザクションが持っているロックを待ってブロックされました。

3
Colin 't Hart