Redis 乐观锁与悲观锁

package com.mobanker.feature.credit.business.redis;

import javax.annotation.Resource;

import com.mobanker.feature.credit.common.constant.FeatureConstants;
import com.mobanker.feature.credit.common.utils.DateKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.dianping.cat.message.Event;
import com.mobanker.framework.redis.template.RedisClientTemplate;


@Component(value="redisBusiness")
public class RedisBusinessImpl implements RedisBusiness {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Resource
    private RedisClientTemplate redisClientTemplate;

    @EETransaction(type = "business",name="RedisBusinessImpl.getValue")
    public String getValue(String key) {
        EE.logEvent("Monitor_business", "RedisBusinessImpl.getValue:", Event.SUCCESS, key);

        return redisClientTemplate.get(key);
    }

    @EETransaction(type = "business",name="RedisBusinessImpl.lock")
    public int lock(String key) {
        EE.logEvent("Monitor_business", "RedisBusinessImpl.lock:", Event.SUCCESS, key);

        logger.info("进入lock:key:{}", key);
        int flag = redisClientTemplate.setnx(key, getLockValue()).intValue();
        logger.info("进入lock:key:{},{}", key,"setnx状态:"+flag);
        if(flag==1){//拿到锁
            redisClientTemplate.expire(key, FeatureConstants.System.REDIS_LOCK_EXPIRE);
            return flag;
        }
        logger.info("进入lock:key:{},{}", key,"setnx 未获取锁");
        //key值存在判断是否过期
        String oldTime = redisClientTemplate.get(key);
        if(oldTime==null){
            return flag;
        }
        logger.info("进入lock:key:{},{}", key,"oldTime:"+ DateKit.compareTime(oldTime));
        if(DateKit.compareTime(oldTime)){
            oldTime = redisClientTemplate.getSet(key, getLockValue());
            //判断时间是否过期,如果过期则拿到锁
            logger.info("进入lock:key:{},{}", key,"如果过期则拿到锁:"+DateKit.compareTime(oldTime));
            if(DateKit.compareTime(oldTime)){
                redisClientTemplate.expire(key, FeatureConstants.System.REDIS_LOCK_EXPIRE);
                flag=1;
            }
        }
        logger.info("进入lock:key:{},{}", key,"结果:"+flag);
        return flag;
    }

    @org.jetbrains.annotations.NotNull
    @EETransaction(type = "business",name="RedisBusinessImpl.getLockValue")
    private String getLockValue(){
        EE.logEvent("Monitor_business", "RedisBusinessImpl.getLockValue:", Event.SUCCESS, "");

        return (DateKit.getNowLongTime()+FeatureConstants.System.REDIS_LOCK_KEY_TIME)+"";
    }


    @EETransaction(type = "business",name="RedisBusinessImpl.lockWait")
    public int lockWait(String key) throws InterruptedException {
        int flag = 0;
        logger.info("进入lockWait:key:{}", key);
        int timeout=FeatureConstants.System.REDIS_LOCK_WAIT_TIME*1000;
        while (timeout >= 0) {
            flag=lock(key);
            logger.info("进入lockWait:key:{},while value:{}", key,flag);
            if(flag==1){
                return flag;
            }
            timeout -= FeatureConstants.System.DEFAULT_ACQUIRY_RESOLUTION_MILLIS;
            /*延迟200 毫秒,  这里使用随机时间可能会好一点,可以防止饥饿进程的出现,即,当同时到达多个进程,
             *只会有一个进程获得锁,其他的都用同样的频率进行尝试,后面有来了一些进行,也以同样的频率申请锁,这将可能导致前面来的锁得不到满足.
             *使用随机的等待时间可以一定程度上保证公平性
             */
            Thread.sleep(FeatureConstants.System.DEFAULT_ACQUIRY_RESOLUTION_MILLIS);
        }
        logger.info("进入lockWait:key:{},{}", key,"结果:"+flag);
        EE.logEvent("Monitor_business", "RedisBusinessImpl.lockWait:", Event.SUCCESS, key);

        return flag;
    }
    
    

    @EETransaction(type = "business",name="RedisBusinessImpl.unlock")
    public void unlock(String key) {
        redisClientTemplate.del(key);
        EE.logEvent("Monitor_business", "RedisBusinessImpl.unlock:", Event.SUCCESS, key);

    }
    

    @EETransaction(type = "business",name="RedisBusinessImpl.setValue")
    public void setValue(String key, String msg) {
        setValue(key, msg, 0);
        EE.logEvent("Monitor_business", "RedisBusinessImpl.setValue:", Event.SUCCESS, key);


    }


    @EETransaction(type = "business",name="RedisBusinessImpl.setValue")
    public void setValue(String key, String msg, int time) {

        redisClientTemplate.set(key, msg);
        if (time != 0)
            redisClientTemplate.expire(key, time);
        EE.logEvent("Monitor_business", "RedisBusinessImpl.setValue:", Event.SUCCESS, key);

    }

    

    @EETransaction(type = "business",name="RedisBusinessImpl.delValue")
    public void delValue(String key) {
        redisClientTemplate.del(key);
        EE.logEvent("Monitor_business", "RedisBusinessImpl.delValue:", Event.SUCCESS, key);

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦香鸡翅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值