redisson 实现分布式锁

使用场景:如日常的抢票、淘宝商品数量,这是最常见的例子,因为他们的系统都是负载均衡的即是部署多个相同的服务,这样就会造成平常的synchronized 锁达不到同步的目的,这时redisson就是一个很好的处理工具

1、编写配置文件
@Bean
public RedissonClient redissonClient(){
RedissonClient redissonClient=null;
//获取config的实例
Config config = new Config();
//设置请求的URL地址
String url=“redis://106.54.13.167:6379”;
//设置config
config.useSingleServer().setAddress(url);
//通过Redisson来创建一个客户端对象
try{
redissonClient= Redisson.create(config);
logger.info(“创建RedissonClient成功”);
return redissonClient;
}catch (Exception err){
logger.info(“创建RedissonClient失败:”+err.fillInStackTrace());
return null;
}
}

2、 创建一个组件
@Component
public class DistributeRedisLock {
private Logger logger= LoggerFactory.getLogger(getClass());

@Autowired
private RedissonClient redissonClient;

/**
 * 加锁成功....
 * @param lockName
 * @return
 */
public boolean lock(String lockName){
    try {
        if(null==redissonClient){  //如果对象没有注入进来那么说明是有问题的
            logger.info("注入redissonClient对象失败....");
            return false;
        }
        //获取这个锁
        RLock lock = redissonClient.getLock(lockName);
        //锁住了
        lock.lock(30, TimeUnit.SECONDS);
        logger.info("加锁成功.......");
        return true;
    } catch (Exception e) {
        logger.info("不可预期的异常造成了加锁失败....");
       return false;
    }
}


/**
 * 释放锁
 * @param lockName
 * @return
 */
public boolean unlock(String lockName){
    try {
        if(null==redissonClient){  //说明没法释放出问题了....
            logger.info("释放锁失败----"+lockName);
        }
        //获取到这个锁对象
        RLock lock = redissonClient.getLock(lockName);
        if(null!=lock){
           lock.unlock();
           logger.info("释放锁成功....");
           return true;
        }
        return false;
    } catch (Exception e) {
        logger.info("释放锁失败了....");
        return false;
    }
}

}

3、在自己的程序中调用已经声明的组件
@Autowired
private DistributeRedisLock distributeRedisLock;

public String produceStockRedisson(){
String lock=“lock”;
try {
boolean lock1 = distributeRedisLock.lock(lock);
if(true==lock1){//说明加锁成功
int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get(“traintickes”));
//首先要判断下 这个库存是否>0
if (stock > 0) { //说明可以减去库存
int rStock = stock - 1;
//下一步:将真实的库存放到咋们的Redis中去
stringRedisTemplate.opsForValue().set(“traintickes”, String.valueOf(rStock));
logger.info(“扣减库存成功…剩余库存:” + rStock);
} else { //说明不能扣减库存
logger.info(“库存扣减失败、库存是负数、不足…”);
} //已经用了15秒钟
}else{
return “当前的排队人数过多…”;
}
}finally {
distributeRedisLock.unlock(lock);
}
return “抢票成功…”;
}

上一篇:mysql集群之MYSQL CLUSTER


下一篇:利用redis 分布式锁 解决集群环境下多次定时任务执行