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);
} }

redis锁定商品解决并发售卖问题 RedisUtil工具类的更多相关文章

  1. 线程高级应用-心得6-java5线程并发库中同步工具类(synchronizers),新知识大用途

    1.新知识普及 2. Semaphore工具类的使用案例 package com.java5.thread.newSkill; import java.util.concurrent.Executor ...

  2. java操作redis集群配置[可配置密码]和工具类(比较好用)

    转: java操作redis集群配置[可配置密码]和工具类 java操作redis集群配置[可配置密码]和工具类     <dependency>   <groupId>red ...

  3. java操作redis集群配置[可配置密码]和工具类

    java操作redis集群配置[可配置密码]和工具类     <dependency>   <groupId>redis.clients</groupId>   & ...

  4. RedisUtil 工具类

    package com.test; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import red ...

  5. RedisUtil工具类

    转载:http://blog.csdn.net/liuxiao723846/article/details/50401406 1.使用了jedis客户端,对redis进行了封装,包括: 1)使用了re ...

  6. 使用redis分布式锁解决并发线程资源共享问题

    众所周知, 在多线程中,因为共享全局变量,会导致资源修改结果不一致,所以需要加锁来解决这个问题,保证同一时间只有一个线程对资源进行操作 但是在分布式架构中,我们的服务可能会有n个实例,但线程锁只对同一 ...

  7. Java多线程与并发库高级应用-工具类介绍

    java.util.concurrent.Lock 1.Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互 ...

  8. 2018.12.1 web项目中解决乱码问题的一个工具类

    <!-- 配置一个过滤器 编码格式的过滤器 --> <filter> <filter-name>encodeFilter</filter-name> & ...

  9. java Redis工具类

    redis就是一个nosql数据库,做存储做缓存的,java代码中就是嵌入了一个客户端,读取与存储数据而已. 先来一个简单的工具类: package com.ming.redis; import re ...

  10. SpringBoot整合Redis及Redis工具类

    前言 想做一个秒杀项目,问了几个大佬要了项目视频,结果,自己本地实践的时候,发现不太一样,所以写下这篇,为以后做准备. 环境配置 IDE:IDEA 环境:Windows 数据库:Redis Maven ...

随机推荐

  1. 璀璨智行:V2X车路协同智慧交通

    ​V2X车用无线通信技术是指车对外界的信息交换,作为未来智能交通运输系统的关键技术,璀璨智行潜心研究V2X技术,致力于V2X车路协同的落地,在智慧交通领域做出了卓越的贡献. 创业机会点 魏军博表示:& ...

  2. 涨姿势 | 一文读懂备受大厂青睐的ClickHouse高性能列存核心原理

    简介: 本文尝试解读ClickHouse存储层的设计与实现,剖析它的性能奥妙 作者:和君 引言 ClickHouse是近年来备受关注的开源列式数据库,主要用于数据分析(OLAP)领域.目前国内各个大厂 ...

  3. 居然之家:核心业务系统全面上云,采用PolarDB替代传统商业数据库

    ​简介: 国内家居零售龙头企业居然之家完成7大核心业务系统全面上云工作,并实现ERP等核心业务系统从传统商业数据库向阿里云PolarDB云数据库的替换,助力业务系统整体处理能力提升50%以上,弹性能力 ...

  4. WPF 将控件放入到 UserControl 里获取 HwndSource 为空的情况

    本文记录将 WPF 控件放入到 UserControl 里,如果此 UserControl 没有被设置 Visibility 为可见过,那么放在此 UserControl 内的控件将获取不到 Hwnd ...

  5. dotnet 教你写一个可以搞炸本机所有 WCF 应用的程序方法

    作为团队里面挖掘机出身的我,怎么能不多挖一些坑好将小伙伴们都埋进去呢.本文来告诉大家一个有趣且简单的方法,此方法可以将本机的 WCF 玩坏,不敢说真的搞炸本机所有 WCF 应用,但搞炸大部分基于 WC ...

  6. SQL server 自定义工资公式设计

    目的: 工资系统中,在计算各工资项目的时候,用户能自定义公式.这里的讲述是从数据库方设计方面考虑,做简要的数据模拟和实体.存储过程的设计. 收集数据: 1.Employee员工信息数据(Employe ...

  7. EasyRepro与测试自动化( 一) 概览

    EasyRepro是一个框架,允许在特定的Dynamics 365组织上执行自动化UI测试.你可以使用它来自动化冒烟测试.回归测试和负载测试等.该框架是由开源项目Selenium构建的,Seleniu ...

  8. 【强化学习】Markov Decision processes【二】

    目录 Markov Decision processes Markov Process Markov reward process Markov Decision processes 马尔可夫决策过程 ...

  9. 安装pyenv-win(windows 环境)支持多个python环境管理

    安装pyenv-win(windows 环境)支持多个python环境管理 https://blog.csdn.net/dair6/article/details/129128240

  10. Docker打包程序镜像

    简介 做了一个视频检测程序,它是由golang和c++编写的.因为公司要做私有化部署,因此需要打包成镜像然后放到公司的registry镜像仓库里.之前一直没有去熟悉docker,现在刚好机会来了,咱就 ...