【问题标题】:Redis how to make EVAL script behave like MULTI / EXEC?Redis 如何使 EVAL 脚本表现得像 MULTI / EXEC?
【发布时间】:2020-08-25 21:34:23
【问题描述】:

我在玩 Lua 脚本时注意到的一件事是,在包含多个操作的脚本中,如果在脚本执行的中途抛出错误,那么在错误之前完成的操作实际上会反映在数据库中.这与 MULTI / EXEC 不同,所有操作要么成功要么失败。

例如,如果我有如下脚本:

redis.call("hset", "mykey", "myfield", "val")
local expiry = someFunctionThatMightThrow()
redis.call("expire", "mykey", expiry)

我对此进行了测试,第一次hset 调用的结果反映在redis 中。有什么方法可以让 lua 脚本的行为如此,如果在脚本期间抛出任何错误,那么在该脚本执行期间执行的所有操作都会被还原?

【问题讨论】:

  • 你可以使用 mset 这是原子的,stackoverflow.com/questions/61626398/…
  • @tabreaz 但是任何“集合”的值都可以在脚本内部使用可能抛出的逻辑来计算。
  • 在循环中计算结果并存储在dict中,循环完成后从dict调用redis。
  • @tabreaz 这仅适用于“设置”。我帖子中的示例只是一个示例,我的问题比这要广泛得多。请参阅帖子中的新示例。
  • 事实上,甚至MULTI/EXEC can not roll back。没有内置的功能,您必须按照@tabreaz 的建议手动回滚。

标签: redis lua


【解决方案1】:

我上面评论的示例脚本,错误手动回滚。注意:语法未经验证。

redis.call("hset", "mykey", "myfield", "val")
local expiry,error = pcall(someFunctionThatMightThrow())
if expiry ~= nil then
  redis.call("expire", "mykey", expiry)
else
  redis.call("hdel", "mykey", "myfield")
end

【讨论】:

    猜你喜欢
    • 2012-06-24
    • 2020-11-08
    • 2021-04-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多