DISCARD:放弃事务
发布时间:2025-06-24 18:51:57 作者:北方职教升学中心 阅读量:141
2、错误处理
在 Lua 脚本中,错误处理是非常重要的。分布式锁
- 1、主要区别在于前者在命令失败时会抛出一个错误,而后者则会返回一个错误对象。
// 监控键redisTemplate.watch("key");redisTemplate.multi();redisTemplate.boundValueOps("key").set("value3");// 提交事务List<Object> results = redisTemplate.exec();if (results == null) { // 事务执行失败,可以选择重新尝试}redisTemplate.unwatch();
Redis 事务通过 MULTI/EXEC 命令来实现,将多个命令打包成一个事务,确保这些命令的连续执行,同时提供基本的隔离性和一致性支持。脚本参数
- KEYS:包含脚本传递的键列表,使用 redis.call 或 redis.pcall 执行 Redis 命令时,可以通过 KEYS 访问这些键。
1、获取和设置键的值local key = KEYS[1]local value = ARGV[1]redis.call("SET", key, value)return redis.call("GET", key)
2.2、加锁
- 1.2、编写
一、
可重入性:同一个节点可以多次获取锁,不会被阻塞。2.3、错误处理
四、为了防止这种情况,可以为锁设置过期时间,当锁超时后自动释放。Redis 自版本 2.6 以来内置了 Lua 解释器,并可以通过使用 EVAL 命令执行 Lua 脚本。特性- 互斥性:在任何时刻只有一个节点可以获得锁。
四、
- SCRIPT FLUSH:从服务器缓存中移除所有 Lua 脚本。
2、步骤
3、高可用:锁服务应该是高可用的,不能因为锁服务故障影响系统整体性能。EVALSHA:通过脚本的 SHA1 哈希值执行脚本以提高执行效率。SCRIPT EXISTS:检查服务器中是否已经缓存了指定的脚本。释放锁privateRedisTemplate<String,Object>redisTemplate;privatestaticfinalStringLOCK_PRE="redis:lock:";privateDefaultRedisScript<String>lockScript;@PostConstructpublicvoidinit(){Stringsb ="if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end ";this.lockScript =newDefaultRedisScript<>();this.lockScript.setScriptText(sb);this.lockScript.setResultType(String.class);}publicStringexecuteLuaScript(Stringkey,Stringvalue){returnredisTemplate.execute(lockScript,Collections.singletonList(key),value);}publicStringsetnx(Stringkey,Stringvalue,longseconds){returnthis.redisTemplate.execute((RedisCallback<String>)connection ->{ObjectnativeConnection =connection.getNativeConnection();Stringresult =null;if(nativeConnection instanceofJedisCommands){result =((JedisCommands)nativeConnection).set(key,value,SetParams.setParams().nx().px(seconds));}if(!StringUtils.isEmpty(key)&&!StringUtils.isEmpty(result)){log.debug("Get lock {} at {}",key,System.currentTimeMillis());}returnresult;});}publicvoidreleaseLockWithLua(StringlockName,Stringidentifier){StringlockKey =LOCK_PRE+lockName;try{executeLuaScript(lockKey,identifier);}catch(Exceptionex){Objectvalue =this.redisTemplate.opsForValue().get(lockKey);if(value !=null&&identifier.equals(value.toString())){this.redisTemplate.delete(lockKey);}}}