UnitLock
in package
エントリー単位のユニット更新を直列化するアドバイザリロック(MySQL GET_LOCK)
changeRevision()(リビジョン切替)と saveAllUnits() 等(作業領域の通常保存)は、 いずれも同一の column テーブル・同一エントリーに対して「全削除→再登録」を行うが、 互いを意識した排他制御を持たない。両者が同時実行されると削除・再登録のタイミングが 重なり、双方が登録したユニットの両方が残ってしまう(CMS-7863)。 このクラスは、その一連の処理をエントリー単位で直列化する。
Table of Contents
Constants
- DEFAULT_TIMEOUT = 10
- LOCK_NAMESPACE = 'acms_unit'
Properties
- $depth : array<string, int>
- ロック名 => 同一プロセス内での保持(ネスト)回数。 changeRevision() が内部で saveAllUnits() を呼ぶなど、同一エントリーに対する ロック取得がネストするケースを、GET_LOCK を再度呼ばずに素通りさせるために使う。
Methods
- generateLockName() : string
- アドバイザリロック名を生成する。
- withLock() : T
- エントリー単位のロックを取得して $callback を実行し、完了後に解放する。
Constants
DEFAULT_TIMEOUT
private
mixed
DEFAULT_TIMEOUT
= 10
LOCK_NAMESPACE
private
mixed
LOCK_NAMESPACE
= 'acms_unit'
Properties
$depth
ロック名 => 同一プロセス内での保持(ネスト)回数。 changeRevision() が内部で saveAllUnits() を呼ぶなど、同一エントリーに対する ロック取得がネストするケースを、GET_LOCK を再度呼ばずに素通りさせるために使う。
private
static array<string, int>
$depth
= []
Methods
generateLockName()
アドバイザリロック名を生成する。
public
static generateLockName(int $entryId) : string
GET_LOCK はMySQLサーバ全体で共有され、ロック名は最大64文字という制約がある。 DB名・テーブルプレフィックスを名前空間として連結しハッシュ化することで、 同一MySQLサーバを複数インストールで共有しても衝突しない。
Parameters
- $entryId : int
Return values
stringwithLock()
エントリー単位のロックを取得して $callback を実行し、完了後に解放する。
public
withLock(int $entryId, callable(): T $callback[, int $timeout = self::DEFAULT_TIMEOUT ]) : T
Parameters
- $entryId : int
- $callback : callable(): T
- $timeout : int = self::DEFAULT_TIMEOUT
-
ロック取得の待機秒数