redis script 的原子性

redis script 不具备 all or nothing 特性的,可能是 crud 程序猿会遇到,这可能是思维惯性导致的。

redis.call('SET', 'key1', 'value1');
local a = b;
redis.call('SET', 'key2', 'value2');

有以上的脚本,redis 在执行 local a = b; 这一行时,就会报错如下的错误:

(error) ERR Error running script (call to f_71007e955106f406b23cfaba7647eec1081fda7d): 
@enable_strict_lua:15: user_script:1: Script attempted to access nonexistent global variable 'b'

然后后续的代码便不再执行,对于长期习惯于丢异常就会回滚修改的 crud 程序员来说,key1key2 的值肯定没有设置成功。然而事实是,上诉代码是一半成功(成功设置 key1),一半根本没有执行(没有执行到 key2 的位置)。
简而言之,redis script 的原子性特性只是指 redis 只使用一个 lua 解释器执行 script,且是单线程执行 script。但是 script 执行中途报错,是不会将修改回滚的,回滚特性应该属于事务,而 redis 其实是没有严格的事务特性的,redis script 是没有 all or nothing 的特性。但是单条 redis 命令是原子性的,且是 all or nothing 的。

这里贴出 redis 官方的对 script 原子性的描述。

Redis uses the same Lua interpreter to run all the commands. Also Redis guarantees that a script is executed in an atomic way: no other script or Redis command will be executed while a script is being executed. This semantic is similar to the one of MULTI / EXEC. From the point of view of all the other clients the effects of a script are either still not visible or already completed.
However this also means that executing slow scripts is not a good idea. It is not hard to create fast scripts, as the script overhead is very low, but if you are going to use slow scripts you should be aware that while the script is running no other client can execute commands.

详细参考 https://redis.io/commands/eval#atomicity-of-scripts

这个 stackoverflow 上也指出 redis script 的原子性更像是隔离性。error-in-redis-lua-script-after-successful-write-command

What they mean by “atomic” is actually closer to isolation than atomicity: Lua scripts are never concurrent with other Lua scripts or commands.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值