redis集群、并发锁机制减少库存

1.目前并发情况下还有一些问题,当某个进程执行时间大于锁过期时间,这时候还是会有2个进程同时执行减库存代码。
实现思路:可以在加锁的时候开一个子进程去监控 主进程是否完成,未完成则给主进程延时,目前未实现代码。

<?php

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

$numKey = 'STOCK';//库存key

$lockKey = 'LOCK_KEY';//锁key

//initNum($redis, $numKey);//初始化库存(执行一次)

less($redis,$numKey,$lockKey);//减少库存


/**
 * @param Redis   $redis Reids实例
 * @param string  $numKey  库存key
 * @param string  $lockKey 锁key
 * @return string
 */
function less(Redis $redis,$numKey,$lockKey)
{
    //加锁
    //宕机 加超时时间
    $id = session_create_id();//唯一id
    $lock = $redis->setex($lockKey, 10, $id);
    if (!$lock) {
        return '当前服务器繁忙,请稍后再试~';
    }
    //执行过程抛了异常用try finally 优先删除锁
    try{
        $num = $redis->get($numKey);
        if ($num > 0) {
            $numLess = $num - 1;
            $redis->set($numKey, $numLess);
            echo '扣除库存成功'.$numLess;
        } else {
            echo '扣除库存失败';
        }
    } finally{
        if ($id === $redis->get($lockKey)) {//删除自己的锁
            $redis->delete($lockKey);
        }
    }
}

/**
 * 设置缓存初始化库存数量
 *
 * @param Redis $redis
 * @param string $numKey
 */

function initNum(Redis $redis, $numKey)
{
    $redis->set($numKey, 50);
    exit('初始化库存成功');
}
 

关注友儿不迷路

Last modification:September 19th, 2020 at 11:32 pm
如果觉得我的文章对你有用,请随意赞赏