秒杀redis分布式锁
Posted FR13ENDS网络安全
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了秒杀redis分布式锁相关的知识,希望对你有一定的参考价值。
今天在视频中看到了一种redis锁的方法
下面看我的demo代码
<?php
$redis = new \Redis();
if ($redis->connect('127.0.0.1','6379') == false) {
die($redis->getLastError());
}
/**
* [lock 加锁]
* @Author admin@phpsong.com
* @DateTime 2017-11-28T14:48:48+0800
* @param [type] $redis [description]
* @param [type] $key 产品ID
* @param [type] $value 当前时间戳+超时时间戳
* @return [type] [description]
*/
function lock($redis,$key,$value){
//如果可以成功设置就返回true
$ok =$redis->setNx($key,$value);
if($ok){
return true;
}
$currentValue= $redis->get($key);
//锁过期
if(!empty($currentValue) && $currentValue<time()){
//获得上一个锁
$oldValue=$redis->getSet($key,$value);
if(!empty($oldValue) && $oldValue==$currentValue){
return true;
}
}
return false;
}
/**
* [unlock 结锁]
* @Author admin@phpsong.com
* @DateTime 2017-11-28T14:49:27+0800
* @param [type] $redis [description]
* @param [type] $key [description]
* @param [type] $value [description]
* @return [type] [description]
*/
function unlock($redis,$key,$value){
try {
$currentValue=$redis->get($key);
if(!empty($currentValue) && $currentValue==$value){
$redis->del($key);
}
}catch(Exception $e) {
}
}
$product_id=10;
$time=time()+10*1000;
//加锁
$lock=lock($redis,$product_id,$time);
if(!$lock){
exit;
}
$mywatchkey=$redis->get("mywatchkey");
if($mywatchkey<10){
$redis->set("mywatchkey",$mywatchkey+1);
}
//解锁
unlock($redis,$product_id,$time);
用ab测试过没有问题,上面的代码是用java代码修改过来的
java代码的锁文件
package com.imooc.sell.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Slf4j
@Component
public class RedisLock {
@Autowired
private StringRedisTemplate stringRedisTemplate;
public boolean lock(String key,String value){
if(stringRedisTemplate.opsForValue().setIfAbsent(key,value)){
return true;
}
String currentValue=stringRedisTemplate.opsForValue().get(key);
if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue)<System.currentTimeMillis()){
String oldValue=stringRedisTemplate.opsForValue().getAndSet(key,value);
if(!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)){
return true;
}
}
以上是关于秒杀redis分布式锁的主要内容,如果未能解决你的问题,请参考以下文章
基于redis集群实现的分布式锁,可用于秒杀商品的库存数量管理,有測试代码(何志雄)
Redis学习Redis分布式锁实现秒杀业务(乐观锁悲观锁)