LOCK TABLES
    tbl_name [AS alias]
      {READ [LOCAL] | [LOW_PRIORITY] WRITE}
    [, tbl_name [AS alias]
      {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ...
UNLOCK TABLES
        LOCK TABLES
        は、現在のスレッドに対してベース テーブル
        (ビュー以外)
        をロックします。もしテーブルが1つでも他のスレッドによってロックされていたら、それは全てのロックを入手するまでブロックします。
      
        UNLOCK TABLES
        は現在のスレッドによって行われたロックを全て明示的にリリースします。スレッドが別の
        LOCK TABLES
        を発行した時、またはサーバへの接続が閉じられた時に、現在のスレッドにロックされている全てのテーブルは暗黙的にロック解除されます。
        UNLOCK TABLES はまた、FLUSH
        TABLES WITH READ LOCK を利用してグローバル
        リード
        ロックを取得した後に、そのロックをリリースする為に利用されます。(FLUSH
        TABLES WITH READ LOCK
        ステートメントによってリード
        ロックされている全てのデータベース内の全てのテーブルをロックする事ができます。詳しくは
        項12.5.5.2. 「FLUSH 構文」
        を参照してください。これは、もし Veritas
        のような時間内にスナップショットを撮る事ができるファイルシステムを持っていると、バックアップを取るのが大変便利な方法になります。)
      
        LOCK TABLES
        を利用する為には、関連するテーブルに対して
        LOCK TABLES 権限と
        SELECT
        権限を持つ必要があります。
      
        LOCK TABLES
        を利用する主な理由は、テーブルを更新する際にトランザクションをエミュレートしたり、スピードを早くしたりする事です。後ほどもう少し詳しく説明します。
      
        テーブル
        ロックは、別のクライアントによる不適切な読み込みや書き込みに対してのみ保護します。ロックを保持しているクライアントは、それがリード
        ロックだとしても、DROP TABLE
        のようなテーブル
        レベル操作を行う事ができます。切り捨て操作はトランザクション
        セーフではないので、もし、アクティブなトランザクションの実行中や、テーブル
        ロックを保持している最中にクライアントがそれを行おうとすると、エラーが発生します。
      
        LOCK TABLES とトランザクション
        テーブルを共に利用する際には、次の事に注意してください。
      
            LOCK TABLES はトランザクション
            セーフではないので、テーブルをロックしようとする前に、全てのアクティブなトランザクションを暗黙的にコミットします。また、トランザクションの開始をすると(例えば
            START TRANSACTION
            を利用して)、明示的に UNLOCK
            TABLES を実行します。(詳しくは
            項12.4.3. 「暗黙のコミットを引き起こすステートメント」
            を参照してください。)
          
            LOCK TABLES を InnoDB
            のようなトランザクション
            テーブルと共に利用する正しい方法は、AUTOCOMMIT
            = 0
            を設定し、トランザクションを明示的にコミットするまでは
            UNLOCK TABLES
            をコールしないという方法です。LOCK
            TABLES
            をコールする時、InnoDB
            は内部的にそれ自身のテーブル
            ロックを取り、そして MySQL
            もそれ自身のテーブル
            ロックを取ります。InnoDB
            は次のコミットでテーブル
            ロックを解除しますが、MySQL がそのテーブル
            ロックを解除するには、 UNLOCK
            TABLES
            をコールする必要があります。InnoDB
            は LOCK TABLES
            のコールの後そのテーブル
            ロックを即座にリリースし、その為にデッドロックが簡単に起きてしまうので、AUTOCOMMIT
            = 1 を持つべきでは有りません。もし
            AUTOCOMMIT=1
            であれば、古いアプリケーションの不必要なデッドロックを防ぐ為に、InnoDB
            テーブル
            ロックを全く取得しないという事に注意してください。
          
            ROLLBACK は MySQL
            の非トランザクション テーブル
            ロックを解除しません。
          
            FLUSH TABLES WITH READ LOCK
            は、グローバル リード
            ロックは取得しますがテーブル
            ロックはしないので、テーブル
            ロックと暗黙的なコミットに関しては
            LOCK TABLES と UNLOCK
            TABLES
            と同じような動作の制約は受けません。詳しくは
            項12.5.5.2. 「FLUSH 構文」 を参照してください。
          
        LOCK TABLES
        を利用する時、ステートメントの中で利用する予定の全てのテーブルをロックしなければいけません。LOCK
        TABLES
        はビューをロックしないので、もし今実行している操作がビューを利用するなら、それらのビューが依存する全てのベース
        テーブルもロックしなければいけません。LOCK
        TABLES
        ステートメントで取得したロックが有効な間は、そのステートメントによってロックされていないテーブルにアクセスする事はできません。また、単一クエリの中でロックされたテーブルを複数回使用する事はできません。各エイリアスに対して別々にロックを取得する必要がある場合には、代わりにエイリアスを利用してください。
      
mysql>LOCK TABLE t WRITE, t AS t1 WRITE;mysql>INSERT INTO t SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES mysql>INSERT INTO t SELECT * FROM t AS t1;
もしステートメントがエイリアスを利用してテーブルを参照するなら、同じエイリアスを利用してテーブルをロックする必要があります。エイリアスを指定しないでテーブルをロックする事はできません。
mysql>LOCK TABLE t READ;mysql>SELECT * FROM t AS myalias;ERROR 1100: Table 'myalias' was not locked with LOCK TABLES
反対に、もしエイリアスを利用してテーブルをロックすると、そのエイリアスを利用してステートメント内でそのテーブルを参照する必要があります。
mysql>LOCK TABLE t AS myalias READ;mysql>SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES mysql>SELECT * FROM t AS myalias;
        もしスレッドがテーブル上で READ
        ロックを取得したら、そのスレッド(そしてそれ以外の全てのスレッド)はテーブルからは読み込む事しかできません。もしスレッドがテーブル上で
        WRITE
        ロックを取得したら、そのロックを保持するスレッドのみがそのテーブルに書き込みができます。ロックが解除されるまで、その他のスレッドはテーブルの読み込み、書き込みからブロックされます。
      
        READ LOCAL と READ
        の違いは、READ LOCAL
        は、ロックされている間に非対立
        INSERT
        ステートメント(並列挿入)が実行される事を許容するという事です。しかし、もしロックを保持している間に
        MySQL の外部でデータベース
        ファイルを複製しようとすると、これを利用する事はできません。
        InnoDB
        テーブルに対しては、READ LOCAL は
        READ と同じです。
      
        WRITE
        ロックは通常、更新がなるべく速く行われるよう、READ
        ロックよりも高い優先順位を持ちます。これは、もし1つのスレッドが
        READ
        ロックを取得し、そして別のスレッドが
        WRITE
        ロックをリクエストすると、後続の
        READ
        ロックリクエストは、WRITE
        スレッドがロックを得て、それをリリースするまで待つ、という意味になります。WRITE
        ロックを待っているスレッドの前に、別のスレッドが
        READ
        ロックを取得するのを許容する為に、LOW_PRIORITY
        WRITE
        を利用する事ができます。READ
        ロックを持つスレッドが無い時に、時間が残っている事が確実である時だけ、LOW_PRIORITY
        WRITE
        ロックを利用しなければいけません。(例外:トランザクション
        モード(自動コミット = 0)の InnoDB
        テーブルに対しては、LOW_PRIORITY
        WRITE ロックは通常の WRITE
        ロックのように機能し、待機中の
        READ ロックに先行します。)
      
        LOCK TABLES
        は次のように機能します。
      
ロックされる全てのテーブルを内部定義順に並べ替えます。ユーザの立場からは、この順番は定義されていません。
もしそのテーブルが読み込みと書き込みの両方についてロックされるなら、読み込みロックの前に書き込みロックを行ってください。
スレッドが全てのロックを得るまで、テーブル1つずつにロックをして下さい。
        .この方法は、テーブル
        ロックにデッドロックが起きない事を保証します。:しかし、この方法について知っておかなければいけない事があります。もしテーブルに対して
        LOW_PRIORITY WRITE
        ロックを利用していたら、MySQL は
        READ
        ロックを必要とするスレッドがなくなるまで、この特定のロックを待つ、という意味になります。スレッドが
        WRITE ロックを得て、ロック
        テーブル
        リストの中の次のテーブルのロックを得るのを待っている時、他の全てのスレッドは
        WRITE
        ロックが解除されるのを待ちます。もしこれが、ご利用のアプリケーションにとって深刻な問題となってしまったら、いくつかのテーブルをトランザクション
        セーフ
        テーブルに変換する事を考慮するべきです。
      
        テーブル
        ロックを待っているスレッドを終了させる為に、KILL
        を安全に使用する事ができます。詳しくは
        項12.5.5.3. 「KILL 構文」 を参照してください。
      
        INSERT
        が別のスレッドによって実行されてしまう為、INSERT
        DELAYED
        と共に利用しているテーブルをロック
        してはいけない
        という事に注意してください。
      
        通常、全ての単一 UPDATE
        ステートメントはアトミックなので、テーブルをロックする必要はありません。別のスレッドが現在実行中の
        SQL
        ステートメントの邪魔をする事はできません。しかし、テーブルをロックする事が利益をもたらす場合もいくつかあります。
      
            MyISAM テーブル
            セット上でたくさんの操作を行おうとしているのであれば、利用する予定のテーブルをロックしたほうが操作が速くできます。UNLOCK
            TABLES がコールされるまで、MySQL
            はロックされたテーブルのキー
            キャッシュをフラッシュしないので、MyISAM
            テーブルをロックすると、挿入、更新、削除のスピードを速くします。通常、キー
            キャッシュは各 SQL
            ステートメントの後でフラッシュされます。
          
            テーブルをロックする事のマイナス面は、READ
            ロックされたテーブル(ロックを保持している物も含む)を更新できるスレッドが無く、またロックを保持しているテーブル以外は
            WRITE
            ロックされたテーブルにアクセスできるスレッドが無いという事です。
          
            非トランザクション ストレージ
            エンジンに対してテーブルを利用している場合に、もし
            SELECT と UPDATE
            の間に別のスレッドがテーブルを変更しない事を保証したければ、LOCK
            TABLES
            を利用する必要があります。ここに表されている例は、安全に実行する為に
            LOCK TABLES を必要とします。
          
LOCK TABLES trans READ, customer WRITE; SELECT SUM(value) FROM trans WHERE customer_id=some_id; UPDATE customer SET total_value=sum_from_previous_statementWHERE customer_id=some_id; UNLOCK TABLES;
            LOCK TABLES
            無しで、別のスレッドが SELECT
            と UPDATE
            ステートメントの実行の間に、trans
            テーブル内に新しい行を挿入する事が可能です。
          
        多くの場合、相対更新(UPDATE customer SET
        )または
        value=value+new_valueLAST_INSERT_ID()
        関数を利用する事で、LOCK TABLES
        の利用を避ける事ができます。詳しくは
        項1.8.5.3. 「トランザクションとアトミックオペレーション」
        を参照してください。
      
        ユーザ レベルの通知ロック機能
        GET_LOCK() と
        RELEASE_LOCK()
        を利用する事で、テーブルのロックを避ける事ができる場合があります。これらのロックははサーバ内のハッシュ
        テーブルの中に保存され、スピードを速くする目的で
        pthread_mutex_lock() と
        pthread_mutex_unlock()
        を利用して実施されます。詳しくは
        項11.10.4. 「その他の関数」
        を参照してください。
      
ロックの規定に関しての更なる情報は 項6.3.1. 「MySQL のテーブルロック方法」 を参照してください。
        注意:もしロックされたテーブル上に
        ALTER TABLE
        を利用すると、ロックが解除される可能性があります。詳しくは
        項B.1.7.1. 「Problems with ALTER TABLE」
        を参照してください。
      

