LOCK TABLES
および
UNLOCK
TABLES
は、トランザクションの使用と次のように対話します。
LOCK TABLES
はトランザクションセーフではないため、テーブルをロックしようとする前に、アクティブなトランザクションをすべて暗黙的にコミットします。
UNLOCK
TABLES
は、アクティブなトランザクションをすべて暗黙的にコミットしますが、これが行われるのは、テーブルロックを取得するために
LOCK TABLES
が使用された場合のみです。たとえば、次の一連のステートメントでは、UNLOCK
TABLES
がグローバルな読み取りロックを解放しますが、有効なテーブルロックがないためにトランザクションはコミットされません。
FLUSH TABLES WITH READ LOCK; START TRANSACTION; SELECT ... ; UNLOCK TABLES;
トランザクションを
(たとえば、START
TRANSACTION
によって)
開始すると、現在のトランザクションがすべて暗黙的にコミットされ、既存のロックが解放されます。
トランザクションのコミットが暗黙的に引き起こされるほかのステートメントでは、既存のロックは解放されません。このようなステートメントのリストについては、項8.4.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
はテーブルロックを解放しません。
FLUSH
TABLES WITH READ LOCK
は、グローバル読み取りロックは取得しますがテーブルロックはしないので、テーブルロックと暗黙的なコミットに関しては
LOCK TABLES
と
UNLOCK
TABLES
と同じような動作の制約は受けません。項8.5.6.3. 「FLUSH
構文」
を参照してください。