redis分布式锁 即setNx

如有错误希望指出,谢谢

  1. 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();
            }
        }
    }
  1. 锁的方法
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();
	            }
	        }
	 }
}	    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值