LoginSignup
6

More than 5 years have passed since last update.

MySQLのロック機能

Posted at

排他ロック共有ロックではなく、innoDBやそこら辺でもなく、内部レベル行ロックテーブルロックでもなく、GET_LOCK関数のメモ書き。

MySQLにあるLock機能があって、任意の名前のロックを作成する事ができる。何それ知らないって言ったら笑われたのを今頃思い出した。MySQLを使ってファイルロックをする感じ。

使い方

IS_FREE_LOCK, GET_LOCK, RELEASE_LOCK を使う。

  • IS_FREE_LOCK(str)
    • 文字列strのロックが使えるか確認する。 1 が帰ってきた時は使用可能
  • GET_LOCK(str, timeout)
    • timeout秒だけ文字列strで指定されたロックの取得を試みる。timeoutが負の時は無制限。取れるまで待つ。
  • RELEASE_LOCK(str)
    • ロックを解除する。1 の時は成功を表す

実験

ターミナル1とターミナル2を作り、それぞれ別セッションで mysql につなげる。

mysqlデータベース上に time ロックを作ってゴニョゴニョ

mysql> SELECT GET_LOCK('time', 10);
+----------------------+
| GET_LOCK('time', 10) |
+----------------------+
|                    1 |
+----------------------+
1 row in set (0.00 sec)

mysql> 

time のロックが取れたので、ターミナル2でLOCK

mysql> SELECT IS_FREE_LOCK('time');
+----------------------+
| IS_FREE_LOCK('time') |
+----------------------+
|                    0 |
+----------------------+
1 row in set (0.00 sec)

mysql> SELECT GET_LOCK('time', 10);
+----------------------+
| GET_LOCK('time', 10) |
+----------------------+
|                    0 |
+----------------------+
1 row in set (10.08 sec)

mysql> SELECT GET_LOCK('TIME', 10);
+----------------------+
| GET_LOCK('TIME', 10) |
+----------------------+
|                    0 |
+----------------------+
1 row in set (10.07 sec)

mysql> 

期待通り0を返してきている。ついでに time を大文字の TIME にしてみたら 0 を返した。

ターミナル2からロックが開放されない事を確認してみる。

mysql> select RELEASE_LOCK('time');
+----------------------+
| RELEASE_LOCK('time') |
+----------------------+
|                    0 |
+----------------------+
1 row in set (0.00 sec)

mysql> SELECT IS_FREE_LOCK('time');
+----------------------+
| IS_FREE_LOCK('time') |
+----------------------+
|                    0 |
+----------------------+
1 row in set (0.00 sec)

GET_LOCKで取得したロックは、セッションが切れたら自動的に解放されるはずなので試してみる。

mysql> ^DBye
(py2) [yasui@YASUI-MBP1: 17-05-30 17:37]~ $ 

ターミナル1のpromptには、17時37分が表示されている。ターミナル2の方で使えるか確認をする。

mysql> select CURRENT_TIME;
+--------------+
| CURRENT_TIME |
+--------------+
| 17:38:09     |
+--------------+
1 row in set (0.00 sec)

mysql> SELECT IS_FREE_LOCK('time');
+----------------------+
| IS_FREE_LOCK('time') |
+----------------------+
|                    1 |
+----------------------+
1 row in set (0.00 sec)

1を返してきたので使える。

使えるシーンと言えば、あまりない…かな…

てか名前がLOCKだから影が薄くて……

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6