テーブルロックを待機しているセッションを終了するために、KILL
を安全に使用できます。セクション13.7.6.4「KILL 構文」を参照してください。
INSERT DELAYED
で使用しているテーブルはロックしないでください。挿入は、ロックを保持するセッションではなく、別のスレッドによって処理される必要があるため、この場合の INSERT DELAYED
はエラーになります。
LOCK TABLES
および UNLOCK TABLES
は、ストアドプログラム内では使用できません。
performance_schema
データベース内のテーブルは、setup_
テーブルを除き、xxx
LOCK TABLES
ではロックできません。
LOCK TABLES
ステートメントが有効になっている間、次のステートメントは禁止されます。CREATE TABLE
、CREATE TABLE ... LIKE
、CREATE VIEW
、DROP VIEW
、およびストアドファンクション、ストアドプロシージャー、イベントでの DDL ステートメント。
一部の操作では、mysql
データベース内のシステムテーブルにアクセスする必要があります。たとえば、HELP
ステートメントにはサーバー側のヘルプテーブルの内容が必要であり、また CONVERT_TZ()
はタイムゾーンテーブルの読み取りが必要になる可能性があります。サーバーは、ユーザーが明示的にロックしなくても済むように、必要に応じてシステムテーブルを読み取りに対して暗黙的にロックします。次のテーブルは、今説明したように処理されます。
mysql.help_category
mysql.help_keyword
mysql.help_relation
mysql.help_topic
mysql.proc
mysql.time_zone
mysql.time_zone_leap_second
mysql.time_zone_name
mysql.time_zone_transition
mysql.time_zone_transition_type
これらのテーブルのいずれかに対する WRITE
ロックを LOCK TABLES
ステートメントで明示的に設定する場合は、そのテーブルがロックされる唯一のテーブルである必要があります。ほかのどのテーブルも、同じステートメントではロックできません。
1 つの UPDATE
ステートメントはすべてアトミックであるため、通常、テーブルをロックする必要はありません。現在実行中の SQL ステートメントを、ほかのどのセッションも妨げることはできません。ただし、テーブルのロックによって利点が得られる可能性のある場合がいくつかあります。
-
一連の
MyISAM
テーブルに対して多くの操作を実行しようとしている場合は、使用しようとしているテーブルをロックする方がはるかに高速です。MyISAM
テーブルをロックすると、MySQL はロックされたテーブルのキーキャッシュをUNLOCK TABLES
が呼び出されるまでフラッシュしないため、そのテーブルに対する挿入、更新、または削除が高速化されます。通常、キーキャッシュは各 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_statement WHERE customer_id=some_id; UNLOCK TABLES;
LOCK TABLES
を使用しない場合は、SELECT
ステートメントとUPDATE
ステートメントの実行の間に、別のセッションによってtrans
テーブルに新しい行が挿入される可能性があります。
多くの場合は、相対的な更新 (UPDATE customer SET
) または value
=value
+new_value
LAST_INSERT_ID()
関数を使用することによって LOCK TABLES
の使用を回避できます。セクション1.7.2.3「トランザクションおよびアトミック操作の違い」を参照してください。
場合によっては、ユーザーレベルのアドバイザリロック関数 GET_LOCK()
および RELEASE_LOCK()
を使用してテーブルのロックを回避することもできます。高速化のために、これらのロックはサーバーのハッシュテーブル内に保存され、pthread_mutex_lock()
と pthread_mutex_unlock()
で実装されます。セクション12.18「その他の関数」を参照してください。
ロックポリシーの詳細は、セクション8.10.1「内部ロック方法」を参照してください。