自学内容网 自学内容网

PHP批量操作加锁

  • 对于批量操作进行加锁,防止重复提交和数据库冲突

  • register_shutdown_function() 函数,register_shutdown_function 用于注册一个在脚本执行完毕或发生致命错误时调用的函数。这意味着 register_shutdown_function 注册的函数会在脚本的正常执行流程结束后调用,而不是立即执行。代码的执行顺序如下:

    1. 注册一个 shutdown 函数,该函数在脚本结束时调用 LockService::remove($lockKey)。
    2. 执行 $value = 1;。
    3. 脚本继续执行后续的代码。
    4. 当脚本执行完毕或发生致命错误时,调用注册的 shutdown 函数。

$lockKey = 'store:pop:plant:operation'.$storeId;
//判断锁是否存在
if (LockService::has($lockKey, 5)) {
    $this->error('正在处理,请勿重复提交');
}
//register_shutdown_function
register_shutdown_function(function ($lockKey) {
    LockService::remove($lockKey);
}, $lockKey);

LockService服务类

<?php

namespace app\common\service;

class LockService
{
    /**
     * 判断是否有锁
     * @param string $key        锁Key
     * @param int    $ttl        锁时间(秒)
     * @param bool   $refreshTtl 是否重置锁时间
     * @return bool
     * @throws \RedisException
     */
    public static function has(string $key, int $ttl = 5, bool $refreshTtl = true): bool
    {
        $res = RedisService::handle()->incr(self::buildKey($key));

        if ($refreshTtl || $res === 1) {
            RedisService::handle()->expireAt(self::buildKey($key), time() + $ttl);
        }

        return $res !== 1;
    }

    /**
     * 移除锁
     * @param string $key
     * @return void
     * @throws \RedisException
     */
    public static function remove(string $key)
    {
        RedisService::handle()->del(self::buildKey($key));
    }

    /**
     * 获取锁定次数
     * @param string $key
     * @return false|mixed|\Redis|string
     * @throws \RedisException
     */
    public static function times(string $key)
    {
        return RedisService::handle()->get(self::buildKey($key));
    }

    private static function buildKey(string $key): string
    {
        return 'lock:' . $key;
    }
}

原文地址:https://blog.csdn.net/weixin_40534405/article/details/143872361

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!