原有 Lua 实验中,旧 owner-a 请求删除时保留当前 owner-b;owner-b 匹配时才删除,键不存在则返回零。未捕获的 redis.call 错误保留此前写入但停止后续语句;明确的 NOSCRIPT 表示代码缺失。

Redis Lua 脚本执行时不被穿插

Redis Lua 脚本可以先读取数据、判断条件,再更新数据,而不让另一个客户端的命令插进这些步骤之间。但这不意味着每个语句都会成功,也不意味着后面发生错误时会撤销前面的写入,更不意味着执行结果自动具备持久性。原子执行与失败回滚,是必须拆开理解的两个问题。 原有 Lua 实验中,旧 owner-a 请求删除时保留当前 owner-b;owner-b 匹配时才删除,键不存在则返回零。未捕获的 redis.call 错误保留此前写入但停止后续语句;明确的 NOSCRIPT 表示代码缺失。 仅为原有实验示意,本轮未重跑。 把判断放在数据旁边 例如,仅当令牌仍属于当前持有者时才删除它。客户端先 GET、稍后再 DEL,中间可能已经被新持有者替换了值;随后删除就误伤了别人。脚本可以在同一次执行中比较当前值,匹配才删除。因此旧持有者即使带着之前读到的令牌来操作,也不会直接删除新持有者的值。 脚本应通过 redis.call 访问 Redis 数据,这正是脚本接口的用途。沙箱不提供普通文件系统或网络访问,不能把邮件、支付或文件读写搬进脚本。所有会访问的键都应通过 KEYS 传入,普通值用 ARGV,不要根据数据库里读出的内容临时拼接键名。Redis Cluster 中的常规多键使用还要求相关键位于同一哈希槽。 ...

一月 11, 2028 · 3 分钟 · XB Field Notes