ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

redis 分布式锁

2022-02-18 22:01:36  阅读:127  来源: 互联网

标签:加锁 return string lock redis key 分布式


背景:秒杀服务中要写一个定时任务:活动到期时给order微服务发送关闭订单的通知。这需要改变数据库表中的数据,而集群中服务是多节点的方式进行部署,会出现并发执行的情况,所以采用的redis的分布式锁的实现方式。
Redis 锁(setNx)
特点: 如果没有获取到锁,请求会被丢弃。 只适合 消息队列 和定时任务场景

点击查看代码
 public function sendEndNotice()
    {
        $lock = new QueueLockLogic(LimitCFG::CLOSE_LOCK_KEY);
        $lock_res = $lock->lock(LimitCFG::CLOSE_LOCK_KEY);
        if (!$lock_res) return false;
        //...
        $res = $lock->unlock(LimitCFG::CLOSE_LOCK_KEY);
        return $res;
    }
	
	
	//再附上一个应用于砍价服务中消息队列的
	加锁:
        $uniqueKey = "bargain:cmq:upOrderStatus:$storeId_$branchId_$orderId_$status"; 
        $lock = new QueueLockLogic($uniqueKey);
        $lockRes = $lock->lock($uniqueKey);
        if (!$lockRes){
            throw new ErrException(ExceCode::E13161);
        }

		.....

	解锁:
	  $res = $lock->unlock($uniqueKey);

	
	===================方法原型============================
namespace App\Models\Logic;

use Swoft\Redis\Redis;
use Swoft\App;


/**
 * Class QueueLockLogic
 * @package App\Models\Logic
 */
class QueueLockLogic
{
	private $redis;

	private $prefix;

	/**
	 *
	 * @param
	 */
	public function __construct(string $redisPrefix)
	{
		$this->redis = App::getBean(Redis::class);
		$this->prefix = $redisPrefix;
	}

	/**
	 * 获取redis键
	 *
	 * @param string $unique
	 * @return string
	 */
	public function getKey(string $unique): string
	{
		return $this->prefix . $unique;
	}

	/**
	 * 获取锁
	 * 返回:
	 *     true: 说明获得锁,
	 *     false: 说明获得锁失败
	 *
	 * @param string  $key
	 * @param integer $expireTime
	 * @return boolean
	 */
	public function lock(string $key, int $ttl = 60): bool
	{
		//加锁
		$res = $this->redis->setNx($key, time() + $ttl);

		if ($res === 0) { //加锁失败
			//检测锁是否过期
			$expireTime = $this->redis->get($key);
			if ($expireTime < time()) { //锁已过期,获取锁
				$oldExpireTime = $this->redis->getSet($key, time() + $ttl);    //在查询期间可能有别的进程加锁,也许已经加锁成功。
				if ($oldExpireTime < time()) {//加锁成功
					return true;
				}//即便加锁失败,重置了key的值也相差无几可忽略
			}

			return false;
		}

		return true;
	}

	/**
	 * 解锁
	 * @param string $key
	 * @return bool
	 */
	public function unlock(string $key): bool
	{
		return $this->redis->delete($key) > 0;
	}

}

标签:加锁,return,string,lock,redis,key,分布式
来源: https://www.cnblogs.com/xjcyue/p/15911388.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有