Redis的stringRedisTemplate执行lua脚本报错 io.lettuce.core.output.ValueOutput does not support set(long)解决

在用StringRedisTemplate执行脚本的时候,要注意传入的值和返回的值能不能成功地类型转换...

开始我用stringRedisTemplate.execute(new DefaultRedisScript<>(lua, String.class), list, 1),一直报错class java.lang.XXX cannot be cast to class java.lang.String,发现是最后的args是1,应该改为"1",string类型才好传递过去。

然后是返回值的时候一直报错io.lettuce.core.output.ValueOutput does not support set(long),这就是脚本里面可能写了return 1,return 0,return一个数字,但是new DefaultRedisScript<>(lua, String.class)中用的是String.class,所以没法把数字转换为String.class,就需要改一下转换的类型为Integer.class,但这样可能其他的返回值是其他类型,依旧存在问题,就需要改lua脚本,把返回值改为string类型。

比如我原来的lua脚本:

String lua = "if ( redis.call('hexists',KEYS[2],KEYS[3]) == 1 ) then " + //说明已经抢过了
                " return 0 " +
                " elseif ( redis.call('llen',KEYS[1]) == 0 ) then " +//说明已经抢完了
                " return -1 " +
                " else " +//说明开始抢红包
                " local number = redis.call('lpop',KEYS[1]) " +
                " redis.call('hset',KEYS[2],KEYS[3],number) " +
                " return number " +
                " end ";

返回的是int或double类型(nubmer是double),Template里设置不好返回类型,就统一把返回值改为string类型:

String lua = "if ( redis.call('hexists',KEYS[2],KEYS[3]) == 1 ) then " + //说明已经抢过了
                " return '已经抢过了' " +
                " elseif ( redis.call('llen',KEYS[1]) == 0 ) then " +//说明已经抢完了
                " return '已经抢完了' " +
                " else " +//说明开始抢红包
                " local number = redis.call('lpop',KEYS[1]) " +
                " redis.call('hset',KEYS[2],KEYS[3],number) " +
                " return tostring(number) " +
                " end ";

这样返回值就都是string,就能直接用stringRedisTemplate.execute(new DefaultRedisScript<>(lua, String.class), list, "1")了。

你可能感兴趣的:(redis学习,redis,lua,java)