写入命令成功后,Redis Lua脚本中出现错误
根据Redis文档,lua脚本以原子方式执行。我假设这也意味着scipt作为事务运行,也就是说,脚本中的所有write命令要么成功,要么失败。 但我注意到,即使脚本稍后返回错误,写命令更改也会持续 例如,从redis cli运行以下命令后,键“k”的值为“1”,即使脚本本身返回关于访问全局变量的错误:写入命令成功后,Redis Lua脚本中出现错误,lua,redis,Lua,Redis,根据Redis文档,lua脚本以原子方式执行。我假设这也意味着scipt作为事务运行,也就是说,脚本中的所有write命令要么成功,要么失败。 但我注意到,即使脚本稍后返回错误,写命令更改也会持续 例如,从redis cli运行以下命令后,键“k”的值为“1”,即使脚本本身返回关于访问全局变量的错误: eval "redis.call(\"set\",KEYS[1],1) return x>1" 1 "k" 这是预期的吗?我错过了什么?我在Windows上运行的是2.8.12版。他们所说
eval "redis.call(\"set\",KEYS[1],1) return x>1" 1 "k"
这是预期的吗?我错过了什么?我在Windows上运行的是2.8.12版。他们所说的“原子”实际上更接近于隔离,而不是原子性:Lua脚本从不与其他Lua脚本或命令并发
确切的措辞是:
Redis保证脚本以原子方式执行:没有其他方式
脚本或Redis命令将在脚本运行时执行
执行。这种语义与MULTI/EXEC非常相似。
从所有其他客户的角度来看
脚本仍然不可见或已完成
据我所知,Redis中没有回滚。所有更改都在RAM中完成,并在Lua脚本完成后写入磁盘,但不管是完成正常还是出现错误,数据都会被写入。如果您想使用NoSQL数据库实现真正的事务,请尝试Tarantool:您可以在出现错误时停止redis server。例如:
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。原子性意味着脚本要么工作要么不工作,而不是基于事务。或者,换句话说,没有回滚这是我的想法:“脚本要么工作要么不工作”,但完全,而不是部分。“没有回滚”更好地解释了这一点。但愿它在文件里。