如有错误希望指出,谢谢
- redis set 方法以及参数含义
/**
* redis set 方法时添加时间 和格式
* 参数用法 nxxx 对应 NX XX
* NX : not exists, 只有key 不存在时才把key value set 到redis
* XX : is exists ,只有 key 存在是,才把key value set 到redis
* expx 对应 EX PX EX是秒,PX是毫秒
*/
public String set(final String key, final String value, final String nxxx, final String expx,
final long time) {
Jedis jedis = jedisPool.getResource();
try {
return jedis.set(key, value,nxxx,expx,time);
} catch (JedisConnectionException e) {
jedis.disconnect();
throw e;
} finally {
if(jedis!=null){
jedis.close();
}
}
}
- 锁的方法
package kumi.saas.edu.service.util;
import kumi.saas.edu.common.cache.JedisService;
import kumi.saas.edu.common.util.SpringUtil;
import java.util.Collections;
/**
* @author rocky.maple
* @date 2019-06-18 17:43
* 拼团锁
*/
public class RedisLock {
private static JedisService jedisService = SpringUtil.getBean(JedisService.class);
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;
private static final String GROUP_PAYMENT_CHANGE = "group_payment:";
/**
* 尝试获取分布式锁
* @param lockKeyMark 锁 唯一
* @param value 请求标识
* @return
*/
public static boolean redisBalanceChangeLock(Object lockKeyMark,String value) {
String lockCompete = jedisService.set( GROUP_PAYMENT_CHANGE + lockKeyMark, value, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, 600);
return LOCK_SUCCESS.equals(lockCompete);
}
/**
* 释放分布式锁
* @param lockKeyMark 锁 唯一
* @param value 请求标识
* @return 是否释放成功
*/
public static boolean redisBalanceChangeRelease(Object lockKeyMark,String value) {
String lockKey = GROUP_PAYMENT_CHANGE + lockKeyMark;
return releaseDistributedLock(lockKey, value);
}
/**
* 尝试获取分布式锁
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public static boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {
String result = jedisService.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
return LOCK_SUCCESS.equals(result);
}
/**
* 释放分布式锁
* @param lockKey 锁
* @param requestId 请求标识
* @return 是否释放成功
*/
public static boolean releaseDistributedLock(String lockKey, String requestId) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedisService.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
return RELEASE_SUCCESS.equals(result);
}
}
3.锁的用法
/**
* 锁
* @param groupNo 拼团唯一编号
*/
public void redisLock(String groupNo){
String redisLockValue =Thread.currentThread().getName() + "_" + System.currentTimeMillis();
try {
while (true) {
if (RedisLock.redisBalanceChangeLock(groupNo, redisLockValue)) {
//代码逻辑
break;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
log.error("出现中断异常",e);
}
}
}finally {
RedisLock.redisBalanceChangeRelease(groupNo,redisLockValue);
}
}
4.SpringUtil 类
注意:这边如果运行的时候发现 applicationContext = null 时注意 spring 配置 不能为懒加载 具体可以去百度
这边推荐博客 Spring应用 4 ApplicationContextAware应用理解
package kumi.saas.edu.common.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @author maple
* @Title: SpringUtil
* @date 2019/7/8 10:23 AM
*/
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
/**
* 获取applicationContext
* @return 应用程序上下文
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过name获取 Bean.
* @param name 名字
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
* @param clazz 类
* @param <T> 返回
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
* @param name 名字
* @param clazz 类
* @param <T> 返回
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
4.jedisService 中用到方法 类
public class JedisService {
@Autowired
private JedisPool jedisPool;
public Object eval(String script, List<String> keys, List<String> args) {
Jedis jedis = jedisPool.getResource();
try {
return jedis.eval(script, keys, args);
} catch (JedisConnectionException e) {
jedis.disconnect();
throw e;
} finally {
if(jedis!=null){
jedis.close();
}
}
}
public String set(final String key, final String value, final String nxxx, final String expx,
final long time) {
Jedis jedis = jedisPool.getResource();
try {
return jedis.set(key, value,nxxx,expx,time);
} catch (JedisConnectionException e) {
jedis.disconnect();
throw e;
} finally {
if(jedis!=null){
jedis.close();
}
}
}
}