redis锁定商品解决并发售卖问题 RedisUtil工具类

发布时间 2023-12-20 22:58:28作者: oktokeep

redis锁定商品解决并发售卖问题 RedisUtil工具类

redis数据类型介绍:

 

//伪代码,基本思路

//1.出redis,每次在选定商品之后,先检查redis是否已经锁定该商品,避免超卖。
Set<String> cacheList = redisUtilService.getSetValue(redisMapKey);
if(CollectionUtils.isNotEmpty(cacheList)) {
//判断商品等属性,比如租期是否已经重叠等,商品是否已经锁定卖出等,避免重复售卖。
}


//2.入redis,售卖成功,增加到redis中
redisUtilService.setSetValue(redisMapKey, redisMapValueStr);
redisUtilService.expireMinute(redisMapKey, RENTER_TIME_OVERLAPPING_REDIS_EXPIRE_MINUTE);

 

//RedisUtilService.java工具类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class RedisUtilService {
    @Autowired
    private StringRedisTemplate redis;
    

    /**
     * 从redis缓存中取值
     * @param key
     * @return
     */
    public String getValue(String key) {
        return redis.opsForValue().get(key);
    }
    /**
     * 往redis缓存存zset值
     * @param key
     * @param customerId
     * @param inviterCounts
     */
    public void setZsetValue(String key,String customerId,double inviterCounts){
        redis.opsForZSet().add(key, customerId, inviterCounts);
    }

    /**
     * Set无序集合赋值
     * @param key
     * @param customerId
     */
    public void setSetValue(String key,String customerId){
        redis.opsForSet().add(key, customerId);
    }

    /**
     * Set无序集合获取
     * @param key
     * @return
     */
    public Set<String> getSetValue(String key){
        return redis.opsForSet().members(key);
    }


   /**
    * 倒序根据score下标取zset值
    * @param key
    * @param start
    * @param end
    * @return
    */
    public Set<TypedTuple<String>> getZsetValue(String key,long start, long end ){ 
        return redis.opsForZSet().reverseRangeWithScores(key, start, end);
    }
    /**
     * 获取value对应的socre
     * @param key
     * @param o
     * @return
     */
    public Double getZsetScore(String key,Object o){
        return redis.opsForZSet().score(key, o);
    }
    /**
     * 获取value对应的排名(倒序)
     * @param key
     * @param o
     * @return
     */
    public Long getZsetRank(String key,Object o){
        return redis.opsForZSet().reverseRank(key, o);
    }
    
    /** 获取redis元素数量
     * @param key
     * @return
     */
    public Long getZsetLength(String key){
        return redis.opsForZSet().size(key);
    }
    /**
     * 有时间期限的往缓存中设值
     * @param key
     * @param value
     * @param second
     */
    public void setValue(String key, String value, Long second) {
        redis.opsForValue().set(key, value, second, TimeUnit.SECONDS);
    }
    
    /**
     * 有时间期限的往缓存中设值
     * @param key
     * @param value
     * @param day
     */
    public void setValueWithDayTTL(String key, String value, Long day) {
        redis.opsForValue().set(key, value, day, TimeUnit.DAYS);
    }

    /**
     * 删除制定key值得缓存
     * @param key
     */
    public void removeKey(String key) {
        redis.delete(key);
    }
    
    public void setObjectValue(String key,Object obj){
        redis.opsForValue().set(key, GsonUtils.toJson(obj));
    }
    
    public void setObjectValue(String key,Object obj,Long second){
        redis.opsForValue().set(key, GsonUtils.toJson(obj),second,TimeUnit.SECONDS);
    }
    
     
    /**
     * 入队(可用作消息队列)
     * @param key
     * @param value
     * @return
     */
    public Long in(String key, String value) {  
        return redis.opsForList().rightPush(key, value);  
    }  
  
    /** 
     * 出队 (可用作消息队列)
     * @param key 
     * @return 
     */  
    public String out(String key) {  
        return redis.opsForList().leftPop(key);  
    }  

    /**
     * 队列长 
     * @param key
     * @return
     */
    public Long length(String key) {  
        return redis.opsForList().size(key);
    }  
    /**
    * 对指定key值 +1,key不存在,默认返回1
    *
    * @Title: increaseByOne
    * @Description:对指定key值 +1
    * @param key
    * @return Long    返回类型
    * @throws
    */
    public Long incrementOne(String key){
        return redis.opsForValue().increment(key, 1L);
    }
    
    /**
    * 对指定key值 +1,key不存在,默认返回1
    *
    * @Title: increaseByOne
    * @Description:对指定key值 +1
    * @param key
    * @return Long    返回类型
    * @throws
    */
    public Long decrementOne(String key){
        return redis.opsForValue().increment(key, -1L);
    }
    /**
     * 对指定key值加减计算 ,key不存在,默认返回1
     *
     * @Title: increaseByNum
     * @Description:对指定key值加减计算
     * @param key
     * @return Long    返回类型
     * @throws
     */
    public Long incrementByNum(String key,Long nums){
        return redis.opsForValue().increment(key, nums);
    }
    
    /**
    * 按指定的key进行上锁,true-加锁成功(名字为key的锁,并设置超时),false-加锁失败(表明已存在对应key的锁,加锁失败应停止后续业务操作)
    *
    * @Title: setIfAbsent
    * @Description: 设定指定key的值,若key值已经存在,设置不成功并返回false,key不存在,设置成功,返回true
    * @param key
    * @param second 过期时间
    * @return Boolean   true-加锁成功(名字为key的锁,并设置超时),false-加锁失败(表明已存在对应key的锁)
    * @throws
    */
    public Boolean checkAndSetLock(String key,long second){
        String lockValue = "Lock";
        boolean res = redis.opsForValue().setIfAbsent(key,lockValue);
        if(res){
            redis.opsForValue().set(key,lockValue,second,TimeUnit.SECONDS);
        }
        return res;
    }


    public void deleteLock(String key){
        redis.delete(key);
    }
    
    public Long getExpire(String key) {
        return redis.getExpire(key, TimeUnit.SECONDS);
    }
    
    public boolean expire(String key,long second) {
        return redis.expire(key, second, TimeUnit.SECONDS);
    }
    
    public boolean expireDay(String key,long day) {
        return redis.expire(key, day, TimeUnit.DAYS);
    }

    public boolean expireMinute(String key,long minute) {
        return redis.expire(key, minute, TimeUnit.MINUTES);
    }

    
    public void setValueHash(String key,String hashKey,String value) {
        
        redis.opsForHash().put(key, hashKey, value);
    }
    
    public List<String> getValuesHash(String key) {
        
        HashOperations<String, String, String> hashOperations = redis.opsForHash();
        List<String> values = hashOperations.values(key);
        return values;
        
    }
    
    public void deleteHashKey(String key,String ...hashKeys){
        redis.opsForHash().delete(key, hashKeys);
    }

    public void deleteSetKey(String key){
        redis.opsForSet().remove(key);
    }

}