在用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[3],number) " +
" return number " +
" end ";
返回的是int或double类型(nubmer是double),Template里设置不好返回类型,就统一把返回值改为string类型:
String lua = "if ( redis.call('hexists',KEYS[3]) == 1 ) then " + //说明已经抢过了
" return '已经抢过了' " +
" elseif ( redis.call('llen',KEYS[1]) == 0 ) then " +//说明已经抢完了
" return '已经抢完了' " +
" else " +//说明开始抢红包
" local number = redis.call('lpop',number) " +
" return tostring(number) " +
" end ";
这样返回值就都是string,就能直接用stringRedisTemplate.execute(new DefaultRedisScript<>(lua,"1")了。