public static function acquire($key)
{
    $oldLock = null;
    while (true) {
        $condition = [
            'key' => $key,
            '$or' => [[
                'expireAt' => null,
            ],[
                'expireAt' => ['$lt' => new \MongoDate()]
            ]]
        ];
        $update = [
            '$setOnInsert' => [
                'key' => $key,
            ],
            '$set' => [
                'locked' => true,
                'expireAt' => new \MongoDate(time() + self::EXPIRE_TIME)
            ]
        ];
        try {
            $oldLock = static::findAndModify($condition, $update, ['upsert' => true]);
            break;
        } catch (yii\mongodb\Exception $e) {
            sleep(self::ACQUIRE_LOCK_INTERVAL);
            continue;
        }
    }
    if (!empty($oldLock)) {
        if (!empty($oldLock['expireAt'])) {
            LogHelper::warning(__METHOD__, 'lock timeout', ['key' => $key]);
            while ($oldLock['locked']) {
                sleep(self::ACQUIRE_LOCK_INTERVAL);
                $oldLock = static::findAndModify(['key' => $key], $update);
            }
        }
    }
}
public static function release($key)
{
    $condition = ['key' => $key, 'locked' => true];
    $update = ['$set' => ['locked' => false, 'expireAt' => null]];
    static::findAndModify($condition, $update);
}