高并发状况下对缓存进行读取-修改操做时,须要原子性操做,Redis自己提供一个一些命令,例如incrby、hincrby自增(减)命令,可是这些命令在有些业务中不适用,这种状况下就能够使用lua脚原本实现多命令的执行(读、写);java
如下lua脚本,一般lua脚本只须要加载一次,而后使用redis返回的hash值进行操做;redis
local local = redis.call('exists', KEYS[1]) if tonumber(local) == 0 then return false end if tonumber(redis.call('get', KEYS[1])) <= 0 then return false end if tonumber(ARGV[1]) > 0 then redis.call('incrby', KEYS[1], ARGV[1]) return true else if tonumber(redis.call('get', KEYS[1])) >= tonumber(ARGV[1]) then redis.call('incrby', KEYS[1], ARGV[1]) return true else return
false
end end
该脚本实现了对库存的读取和修改,该脚本能够在resources文件夹进行统一管理;缓存
在java代码中:并发
try { DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(); redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("/limit.lua"))); redisScript.setResultType(Boolean.class); return redisTemplate.execute(redisScript, Collections.singletonList(key), String.valueOf(mlitimes), String.valueOf(maxCount)); } catch (IOException e) { e.printStackTrace(); }
重点:在集群模式下,若是只在某个节点上传了脚本,在其余节点中会找不到,所以须要判断脚本是否存在,若是不存在,从新上传lua脚本。高并发