报错异常:
io.lettuce.core.RedisCommandExecutionException: ERR Error running script (call to f_68864758a116306c5e412e19726f5d5deba405fb): @user_script:4: ERR value is not an integer or out of range
	at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:147) ~[lettuce-core-6.1.9.RELEASE.jar:6.1.9.RELEASE]
	at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:116) ~[lettuce-core-6.1.9.RELEASE.jar:6.1.9.RELEASE]
	at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:120) ~[lettuce-core-6.1.9.RELEASE.jar:6.1.9.RELEASE]
	at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:111) ~[lettuce-core-6.1.9.RELEASE.jar:6.1.9.RELEASE]
	at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:747) ~[lettuce-core-6.1.9.RELEASE.jar:6.1.9.RELEASE]
	at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:682) ~[lettuce-core-6.1.9.RELEASE.jar:6.1.9.RELEASE]
	at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:599) ~[lettuce-core-6.1.9.RELEASE.jar:6.1.9.RELEASE]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496) ~[netty-transport-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.79.Final.jar:4.1.79.Final]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.79.Final.jar:4.1.79.Final]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]
LUA脚本:
if redis.call("EXISTS",KEYS[1]) == 0 or redis.call("hexists",KEYS[1],ARGV[1]) == 1
then
    redis.call("hincrby",KEYS[1],ARGV[1],1)
    redis.call("expire",KEYS[1],ARGV[2])
    return 1
else
    return 0
end
LUA脚本结合Java使用:
String script = "if redis.call(\"EXISTS\",KEYS[1]) == 0 or redis.call(\"hexists\",KEYS[1],ARGV[1]) == 1\n" +
                "then\n" +
                "    redis.call(\"hincrby\",KEYS[1],ARGV[1],1)\n" +
                "    redis.call(\"expire\",KEYS[1],ARGV[2])\n" +
                "    return 1\n" +
                "else\n" +
                "    return 0\n" +
                "end";
        stringRedisTemplate.execute(new DefaultRedisScript<>(script,Boolean.class), Arrays.asList(lockName),getFieldId(),expire);
异常原因:

在这里插入图片描述

在这里expire我定义的类型是Long类型
排查的问题原因是expire没有初始值,所以此时我给expire赋值初始值默认:
private Long expire = 30L;
启动项目后再重试,发现又出现另外一个错误:
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
发现Long类型转String类型错误,找到报错行数看自己那里用了Long类型,发现了问题原因:

在这里插入图片描述

所以最后的解决办法是将expire转为String类型
stringRedisTemplate.execute(new DefaultRedisScript<>(script,Boolean.class), Arrays.asList(lockName),getFieldId(),String.valueOf(expire));
写在最后:也没有去深究里面为什么开始传Long型的expire参数没有提示报错,简单记录一下,后面有时间再研究一下。
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐