0
votes

One thing I noticed when playing around with Lua scripts is that, in a script containing multiple operations, if an error is thrown halfway through the execution of the script, the operations that completed before the error will actually be reflected in the database. This is in contrast to MULTI / EXEC, where either all operations succeed or fail.

For example, if I have a script like the following:

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

I tested this and the results of the first hset call were reflected in redis. Is there any way to make the lua script behave so that if any error is thrown during the script, then all actions performed during that script execution are reverted?

1
You can use mset which is atomic, stackoverflow.com/questions/61626398/… - tabreaz
@tabreaz But the value of any "set" might be computed inside the script using logic that might throw. - shmth
compute the results in the loop and store in dict, after loop completion invoke redis from dict. - tabreaz
@tabreaz That only works for "set". The example in my post is just an example, my question is much broader than this. See the new example in the post. - shmth
In fact, even MULTI/EXEC can not roll back. There's no built-in to do that, you have to roll back manually, as @tabreaz suggested. - for_stack

1 Answers

1
votes

Sample script for my comment above, on error manually rollback. Note: Syntax is not verified.

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