Redis Lua脚本写入成功后出现错误。

根据 Redis 文档,Lua 脚本具有原子性执行。我认为这也意味着脚本作为事务运行,也就是说,脚本中的所有写入命令要么成功,要么失败。但是,我注意到,即使脚本后来返回错误,写入命令的更改仍会持久化。

例如,在从 redis cli 运行以下命令后,“k” 键的值仍为“1”,尽管脚本本身返回关于全局变量访问的错误:

eval "redis.call(\"set\",KEYS[1],1) return x>1" 1 "k"

这是预期的吗?我错过了什么吗?我在 Windows 上运行 2.8.12 版本。

点赞
用户204011
用户204011

他们所说的“原子性”实际上更接近隔离而非原子性:Lua 脚本永远不会与其他 Lua 脚本或命令同时运行。

确切的措辞如下:

Redis 保证脚本以原子方式执行:在脚本执行时不会执行任何其他脚本或 Redis 命令。这种语义非常类似于 MULTI / EXEC。从所有其他客户端的角度来看,脚本的效果要么仍然不可见,要么已经完成。

2015-02-27 23:26:22
用户5094838
用户5094838

据我所知,Redis没有回滚功能。所有更改都在 RAM 中完成,而在 Lua 脚本完成后将写入磁盘,但无论是完成 Ok 还是出错,数据都将被写入。如果要在 NoSQL 数据库中使用真正的事务,请尝试使用 Tarantool:http://tarantool.org/doc/book/box/atomic.html

2015-07-08 23:31:05
用户6243725
用户6243725

你可以在 Lua 错误时停止 Redis 服务器。例如:

local status, res = pcall(function()
    --在这里写你的代码
end);

if not status then redis.call("SHUTDOWN", "NOSAVE"); end;
return res;

但实际上,我不知道 Redis 是否能够将发生错误前执行的命令记录到 AOF 文件中(我猜不能,因为 Redis 只能在脚本执行完后记录命令)。

此外,你可以添加 usedWriteCommands 变量,并仅在有更改数据的命令时调用 SHUTDOWN NOSAVE

2016-06-18 22:46:33