LoginSignup
1
0

処理をロック、"Lock"

Last updated at Posted at 2023-12-11

Symfony Component Advent Calendar 2023の12日目の記事です。

処理をロック、"Lock"

Lockは、ある処理を重複して実行させない(排他処理)ようにします。Symfony以外でも使えます。

インストール

composer require symfony/lock

使い方

LockFactoryオブジェクトを使り、createLock('{ロック名}')メソッドを実行してロックオブジェクトを取得します。'acquire()`メソッドでロックが取得できればtrueを返します。falseを返せば他で処理が実行されているということになります。

use Symfony\Component\Lock\LockFactory;
use Symfony\Component\Lock\Store\SemaphoreStore;

$store = new SemaphoreStore();
$factory = new LockFactory($store); // Factory作成

$lock = $factory->createLock('sample'); // ロック

if ($lock->acquire()) { // ロックされてない
    // 排他処理したいロジック

    $lock->release(); // ロック解除
} else { // ロックされてる
    
}

有効期限

createLock()時にttlを渡すことで有効期限が設定できます。この際、同じく引数にautoReleaseを設定することで、処理が終わっても自動でロックを解除しないようにできます。(通常は自動でロック解除されます)
また、acquire(true)と引数にtrueを渡すと、処理が終わるまで待機します。これをブロッキングと呼びます。


$memcached = new \MemCached();
$memcached->addServer('localhost', 11211);
$store = new MemcachedStore($memcached);

$factory = new LockFactory($store); // Factory作成

$lock = $factory->createLock(
    'sample',
    ttl: 30, // 有効期限(秒)
    autoRelease: false // 自動で解除するか
);

if ($lock->acquire(true)) { // 別の処理でロックが解除されるまで待機
    // 排他処理
}

共有ロック

ロックは共有ロックがあり、読み込みはできるけど書き込みはできないと言った処理が可能になります。acquireRead()で読み込みロックを取得できます。書き込みロックにしたい場合は今まで通りacquire()を呼び出します。いずれもブロッキングが可能です。


$lock = $factory->createLock('sample');
$lock->acquireRead(true); // 読み込みモードでロック取得。ブロッキングなので他のロックが解除されるまで待機

// 読み込み時にやりたい処理

$lock->aquire(true); // 書き込みモードに変更。同じくブロッキング

// 書き込みモードでやりたい処理

$lock->relase();

ストア

ロックはStoreと呼ばれる箇所にロック情報が作成されます。このStoreにより、できることが変わってくるのでシーンに合わせたStoreを選択する必要があります。

Store Scope Blocking Expiring Sharing
FlockStore local yes no yes
MemcachedStore remote no yes no
MongoDbStore remote no yes no
PdoStore remote no yes no
DoctrineDbalStore remote no yes no
PostgreSqlStore remote yes no yes
DoctrineDbalPostgreSqlStore remote yes no yes
RedisStore remote no yes yes
SemaphoreStore local yes no no
ZookeeperStore remote no no no

※MemcachedStoreはBlockingいけると思う

まとめ

今回はLockでした。排他処理ではお世話になる機能ですが、ストアやサーバの構成などの設定を誤るとロックされない状況になるので、使う際は必ず本番環境(や同等の環境)で試してからお使いください。

1
0
0

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
1
0