Web Artisan Blog - ウェブ アルチザン ブログ

MySQL:LOCK TABLESの注意点:複数のテーブル

SQL (37 items)

2005年06月28日

Research Artisan Pro ←リサーチアルチザンがパワーアップして復活しました!!
MySQLで排他制御を行うには、LOCK TABLESを使用します。
※MyISAMテーブルの場合です。

>MySQL リファレンスマニュアル :: 6.7.5 LOCK TABLES および UNLOCK TABLES 構文
LOCK TABLES では、現在のスレッドのテーブルがロックされます。UNLOCK TABLES では、現在のスレッドが保有しているロックが解除されます。


このテーブル全体にロックをかけるというMySQL独特の排他制御ですが、
以下のように複数テーブルの処理の場合は注意が必要です。

■例:テーブルAとBがあり、テーブルAをロックしてその間にテーブルBの処理も行う。
※思いとしては、テーブルAへのロックでテーブルBにもロックがかかる状態を作りたい。

   //ロック
   $query = "LOCK TABLES A WRITE";
   $rs = mysql_query($query , $connection);

   $query = "SELECT ID FROM A";
   //SQL文実行
   $rs = mysql_query($query , $connection);
      ・
      ・
      ・

   $query = "SELECT ID FROM B";
   //SQL文実行
   $rs = mysql_query($query , $connection);
      ・
      ・
      ・
      ・

   //ロック解除
   $query = "UNLOCK TABLES";
   $rs = mysql_query($query , $connection);



上記ロジックは誤りです。
テーブルBをSELECTした時に、mysql_queryはFALSEを返します。

マニュアルにも明記されていますが、

LOCK TABLES の使用時には、使用するテーブルをすべてロックし、またクエリで使用するエイリアスと同じ名前を使用する必要があります。1 つのクエリで同じテーブルを何度も指定する(エイリアスを使用して)場合は、各エイリアスに対してロックを取得しなければなりません。


つまり、LOCK TABLESを発行した後のクエリー(SQL文)は、
LOCK TABLESに指定したテーブルに対してしか処理できません。

上記例では、

   //ロック
   $query = "LOCK TABLES A WRITE, B WRITE";
   $rs = mysql_query($query , $connection);


とするとか、テーブル毎に、
LOCK TABLESとUNLOCK TABLESを指定するとかの方法があるでしょう。
前の記事 次の記事

Comments

コメントは、まだ書かれていません

Add Comments

Trackback

トラックバックはありません

Trackback URL

http://www.res-system.com/weblog/action.php?action=plugin&name=TrackBack&tb_id=495