根据Redis文档,lua脚本以原子方式执行。我认为这也意味着scipts作为事务运行,也就是说,脚本中的所有写命令都成功或失败。 但是我注意到,即使脚本稍后返回错误,写入命令更改也会持续存在。
例如,在从redis cli运行以下命令后,键" k"有价值" 1",即使脚本本身返回有关访问全局变量的错误:
eval "redis.call(\"set\",KEYS[1],1) return x>1" 1 "k"
这是预期的吗?我错过了什么?我正在Windows上运行2.8.12版本。
答案 0 :(得分:1)
“原子”的含义实际上更接近于孤立而非原子性:Lua脚本永远不会与其他Lua脚本或命令同时发生。
确切的措辞是:
Redis保证脚本以原子方式执行:没有其他 脚本或正在执行时将执行脚本或Redis命令 执行。这种语义与MULTI / EXEC非常相似。 从所有其他客户的角度来看,一个人的影响 脚本仍然不可见或已经完成。
答案 1 :(得分:1)
据我所知,Redis中没有回滚。所有的更改都在RAM中完成,并在Lua脚本完成后写入磁盘,但无论是否完成,或者出错都无关紧要,无论如何都会写入数据。如果您想要使用NoSQL数据库进行实际交易,请尝试使用Tarantool:http://tarantool.org/doc/book/box/atomic.html
答案 2 :(得分:0)
您可以在lua错误时停止redis服务器。例如:
local status, res = pcall(function()
--your code here
end);
if not status then redis.call("SHUTDOWN", "NOSAVE"); end;
return res;
但实际上我并不知道redis是否可以登录在错误之前执行的AOF文件命令(我想它可以'因为redis只能在脚本执行完成后才能记录命令)。
此外,您可以添加usedWriteCommands
变量并仅在命令已更改数据时调用SHUTDOWN NOSAVE。