LOCK TABLES
および UNLOCK TABLES
は、トランザクションの使用との間で次のように通信します。
LOCK TABLES
はトランザクションセーフではないため、テーブルをロックしようとする前に、アクティブなトランザクションをすべて暗黙的にコミットします。-
UNLOCK TABLES
は、アクティブなトランザクションをすべて暗黙的にコミットしますが、これが行われるのは、テーブルロックを取得するためにLOCK TABLES
が使用された場合のみです。たとえば、次の一連のステートメントでは、UNLOCK TABLES
がグローバルな読み取りロックを解放しますが、有効なテーブルロックがないためにトランザクションはコミットされません。FLUSH TABLES WITH READ LOCK; START TRANSACTION; SELECT ... ; UNLOCK TABLES;
トランザクションを (たとえば、
START TRANSACTION
で) 開始すると、現在のトランザクションはすべて暗黙的にコミットされ、既存のテーブルロックが解放されます。FLUSH TABLES WITH READ LOCK
は、グローバルな読み取りロックを取得しますが、テーブルロックは取得しないため、テーブルロックと暗黙的なコミットに関してLOCK TABLES
およびUNLOCK TABLES
と同じ動作には従いません。たとえば、START TRANSACTION
は、グローバルな読み取りロックを解放しません。セクション13.7.6.3「FLUSH 構文」を参照してください。暗黙的にトランザクションのコミットを発生させるその他のステートメントは、既存のテーブルロックを解放しません。このようなステートメントのリストについては、セクション13.3.3「暗黙的なコミットを発生させるステートメント」を参照してください。
-
トランザクションテーブル (
InnoDB
テーブルなど) でLOCK TABLES
およびUNLOCK TABLES
を使用するための正しい方法は、SET autocommit = 0
(START TRANSACTION
ではなく) に続けてLOCK TABLES
を指定することによってトランザクションを開始し、そのトランザクションを明示的にコミットするまでUNLOCK TABLES
を呼び出さないことです。たとえば、テーブルt1
に書き込み、テーブルt2
から読み取る必要がある場合は、次のように実行できます。SET autocommit=0; LOCK TABLES t1 WRITE, t2 READ, ...; ... do something with tables t1 and t2 here ... COMMIT; UNLOCK TABLES;
LOCK TABLES
を呼び出すと、InnoDB
は内部的に独自のテーブルロックを取得し、MySQL は独自のテーブルロックを取得します。InnoDB
は次のコミット時に内部のテーブルロックを解放しますが、MySQL でテーブルロックが解放されるようにするには、UNLOCK TABLES
を呼び出す必要があります。autocommit = 1
を指定すると、LOCK TABLES
の呼び出しの直後にInnoDB
によって内部のテーブルロックが解放され、デッドロックが非常に発生しやすくなる場合があるため、この指定は行わないようにしてください。autocommit = 1
が指定された場合、古いアプリケーションが不必要なデッドロックを回避するのに役立つように、InnoDB
は内部のテーブルロックをまったく取得しません。 ROLLBACK
は、テーブルロックを解放しません。