前言
我们一定会在项目中遇到过这种场景:一段代码中,redis进行多次取值存值,虽然单个redis操作具有原子性,但是redis组合操作就不能保证整体的原子性了,这时候我们可以通过lua脚本来实现redis组合操作的原子性。
Lua脚本能够保证redis所有操作的原子性,但是需要注意,Lua脚本中的命令如果有失败的命令,Lua脚本不会回滚,例如有3条插入语句,第一条执行没报错,第二条执行报错了,那么第一条语句就会插入到redis中。
代码实现
下面以springboot中使用lua脚本为例,可以参考下面的使用方法
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
-
编写配置类
其中”demo.lua”是脚本所在的位置,参考第3步中的位置。
defaultRedisScript.setResultType根据返回值类型的结果自定义,比如可以是String.class。 -
编写lua脚本,下面是一个简单的lua脚本文件demo.lua。将新建的lua脚本放到resources目录下即可
-
代码中使用
直接在controller中使用即可。
redisTemplate.execute方法的第三个参数,如果传字符串,Lua脚本的local expire收到的结果是“100”,注意是带着引号的,所以在tonumber(expire)结果是nil,转化失败,所以,需要在代码里传参的时候,传成数字格式的100,失效时间单位是秒。下图是错误示范,代码中需要将args的100由String类型替换成Integer类型。