Open5
ロックに関して メモ
- 冪等性を持つように
- ロックをとる範囲はなるべく少なく
SELECT FOR UPDATE (MySQL)
特定の行に対して排他ロックを設定するために使用する。
このクエリは、通常、トランザクションの一部として使用され、そのトランザクションがコミットまたはロールバックされるまでロックを保持する。
このロックが解除されるまで、この行を変更する (UPDATE・DELETE)ことはできない。
しかし、他のトランザクションは、この行を含む SELECT クエリを実行することが可能。(ただし、それが FOR UPDATE や LOCK IN SHARE MODE などのロックを伴う SELECT でない限り)
ロック競合
一つのトランザクションがリソースのロックを保持している間、他のトランザクションはそのロックが解放されるまで待機。待ち時間は発生するが、ロックが解放されれば処理は進行する。つまり一時的な待ち時間が発生するが、最終的には処理が進む
共有ロックと排他ロックの競合
- 共有ロック: データの読み取り時に取得され、他のトランザクションからの読み取りを許可するが、データの変更 (書き込み) はブロック
- 排他ロック: データの変更時に取得され、他のトランザクションからの読み取りも書き込みもブロック
排他ロックは読み取りがブロックされるので、既存の共有ロックがすべて解放されるまで取得できない。そのため共有ロックが多数存在し、それぞれのトランザクションが長時間ロックを保持していると、排他ロックの取得が大幅に遅れ、innodb_lock_wait_timeout
(デフォルトは50秒) を超えると、Lock Wait Timeout Exceeded が起きる。