• Lua脚本实现setnx命令


    /**
     * @author Linging
     * @version 1.0.0
     * @since 1.0
     */
    @Component
    public class RedisUtil {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        /**
         * 基于lua脚本实现setnx+expire原子性
         * 使用set命令
         * @param key
         * @param value
         * @param seconds
         * @return
         */
        public Object setnx(String key, String value, Integer seconds){
            String script =
                    " if redis.call('get', KEYS[1]) " +
                    " then return 0; " +
                    " else " +
                    " redis.call('set', KEYS[1], ARGV[1]) " +
                    " redis.call('expire', KEYS[1], ARGV[2]) " +
                    " return 1; " +
                    " end; ";
    
            DefaultRedisScript redisScript = new DefaultRedisScript(script, String.class);
            //指定传递参数序列化方式,参数序列化要支持数字,否则报错
            RedisSerializer argsSerializer = new GenericToStringSerializer<>(Object.class);
            //指定返回结果序列化方式
            RedisSerializer<String> resultSerializer = redisTemplate.getDefaultSerializer();
    
            Object execute = redisTemplate.execute(redisScript,argsSerializer, resultSerializer, Lists.newArrayList(key), value, seconds);
            return execute;
        }
    
    
        /**
         * 基于lua脚本实现setnx+expire原子性
         * 使用setnx命令
         * @param key
         * @param value
         * @param seconds
         * @return
         */
        public Object setnx2(String key, String value, Integer seconds){
            String script =
                    " if redis.call('setnx', KEYS[1], ARGV[1]) == 1 " +
                    " then " +
                    " redis.call('expire', KEYS[1],ARGV[2]) " +
                    " return 1 " +
                    " else " +
                    " return 0 " +
                    " end; ";
    
            DefaultRedisScript redisScript = new DefaultRedisScript(script, String.class);
            //指定传递参数序列化方式
            RedisSerializer argsSerializer = new GenericToStringSerializer<>(Object.class);
            //指定返回结果序列化方式
            RedisSerializer<String> resultSerializer = redisTemplate.getDefaultSerializer();
    
            Object execute = redisTemplate.execute(redisScript,argsSerializer, resultSerializer, Lists.newArrayList(key), value, seconds);
            return execute;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    redis序列化方式对于value的处理区别:

    1.GenericJackson2JsonRedisSerializer、Jackson2JsonRedisSerializer是先将对象转为json,然后再保存到redis,所以,1在redis中是字符串1,所以无法进行加1。
    
    2.JdkSerializationRedisSerializer使用的jdk对象序列化,序列化后的值有类信息、版本号等,所以是一个包含很多字母的字符串,所以根本无法加1。
    
    3.GenericToStringSerializer、StringRedisSerializer将字符串的值直接转为字节数组,所以保存到redis中是数字,所以可以进行加1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    set扩展命令:
    Redis在 2.6.12 版本开始,为 SET 命令增加一系列选项:

    SET key value[EX seconds][PX milliseconds][NX|XX]

    • EX seconds: 设定过期时间,单位为秒
    • PX milliseconds: 设定过期时间,单位为毫秒
    • NX: 仅当key不存在时设置值
    • XX: 仅当key存在时设置值
      set命令的nx选项,就等同于setnx命令,代码过程如下:
    jedis.set(key, value, "NX", "EX", seconds)
    
    • 1
  • 相关阅读:
    Linux|shell编程|拷贝大文件之显示进度条
    深度神经网络的主要模型,神经网络预测模型优点
    阿里云服务器企业级和入门级实例规格有何区别?如何选择?
    Deque初步了解
    static 总结
    《实战》提示框
    (附源码)spring boot校园健康监测管理系统 毕业设计 151047
    ArcGIS绘制北半球俯视投影地图
    RHCE(逻辑卷LVM,NFS服务)
    太空射击第17课: Game Over (結束)
  • 原文地址:https://blog.csdn.net/Linging_24/article/details/126316355