zoukankan      html  css  js  c++  java
  • 基于redis实现分布式锁

     基于redis实现分布式锁,主要原理在于key,每次访问时判断当前key是否存在于redis中,若存在则阻塞,若不存在则加入redis中同时获取redis锁。

    但是java中获取key值,及向redis中塞入key以下是两个操作不是原子性的

      1、 redis.get(key)

      2、redis.setEx(key,60*5)

    当线程A和线程B发生并发时,A和B同时get(key),为null,则代表A和B都可以获取当前锁,从而发生并发问题。

    所以此处使用redis事务来避免此问题发生。

     1  public static boolean lock(String key){
     2        //获取redisTemplate
     3         RedisTemplate redisTemplate= RedisHelper.getTemplate();
     4         Boolean rs = (Boolean) redisTemplate.execute(new RedisCallback(key, 60*5));
     5         return  rs;
     6     }
     7 
     8     public static class RedisCallback implements org.springframework.data.redis.core.RedisCallback<Boolean> {
     9         private byte[] key;
    10         private int expire;
    11 
    12         public RedisCallback(String key,int expire) {
    13             this.expire = expire;
    14             this.key = RedisHelper.getTemplate().getStringSerializer().serialize(key);
    15         }
    16 
    17 
    18         @Override
    19         public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
    20             //开启监听,一旦当前key发生变化,事务将被中断,将不会执行返回null
    21             redisConnection.watch(key);
    22             //若key存在,则获取不到锁
    23             byte[] value= redisConnection.get(key);
    24             if(value!=null){
    25                 return false;
    26             }
    27             //事务块开始
    28             redisConnection.multi();
    29             redisConnection.setEx(key,expire,new byte[]{'Y'});
    30             redisConnection.get(key);
    31             //事务块执行,其返回值为执行事务块呢内所有命令的返回值,也就是上边为何加一条get(key),用于判断执行结果
    32             List<Object> obj = redisConnection.exec();
    33             if(CollectionUtils.isNotEmpty(obj)&&obj.size()==1){
    34                 //成功则获取该锁
    35                 return true;
    36             }
    37             return false;
    38         }
    39     }
  • 相关阅读:
    Linux官方源、镜像源汇总
    python3 pip报错 TypeError: 'module' object is not callable
    2019-11-27:kali 2019-4中文乱码解决方法
    2019-11-26:密码学基础知识,csrf防御
    2019-11-25:信息收集,笔记
    2019-11-24:postgresql数据库安装,最后报错failed to load SQLModule 问题的解决方案
    2019-11-22:xss绕过笔记
    2019-11-20:xss学习笔记
    2019-11-19:无返回的盲型xxe,使用带外读取数据
    2019-11-19:xxe漏洞利用,笔记
  • 原文地址:https://www.cnblogs.com/volare/p/12273292.html
Copyright © 2011-2022 走看看