为什么redis返回部分完成的事务?

pgky5nke  于 2021-06-08  发布在  Redis
关注(0)|答案(1)|浏览(382)

我有一个redis交易使用 multi 在一个 watch 这样地:

redis.watch('my-hash', 'my-normal-key', () => {
   redis
     .multi()
     .hset('my-hash', 'hash-key-1', 1)
     .hset('my-hash', 'hash-key-2', 2)
     .set('my-normal-key', 'test', NX)
     .exec((err, res) => {
        // err is null
        // res is an array with the results of the operations but only the set operation has a null res!
     })
});

然后,我与运行上述命令的多个客户机高并发运行。我注意到,有时候 my-hash 或者 my-normal-key 正在另一个客户端中更改 resexec 命令是 null . 这是完全正确的,我可以理解。
当事务成功执行时, res 是以下形式的数组:

res = [
   [null, 0],     // [err, res] for hset('my-hash', 'hash-key-1', 1)
   [null, 0],     // [err, res] for hset('my-hash', 'hash-key-2', 2)
   [null, 'OK'],  // [err, res] for set('my-normal-key', 'test', NX)
]

但是,在某些时候, res 返回类似于部分失败的内容,如下所示:

res = [
   [null, 0],
   [null, 0],
   [null, 0],
   [null, null],   // the result of the set operation is null!
]

结果 set 操作返回 null ,我认为这意味着另一个客户已经做了更改。但我无法模拟结果如何以这种方式返回。我在redis的最终数据中看到,这确实完成了所有的任务 hset 除了set操作之外的其他操作,这让我想知道事务怎么可能是部分的?
是什么导致了部分交易?它是如何发生的?有没有办法防止这种部分交易的发生?

jdzmm42g

jdzmm42g1#

我不认为这是部分交易的问题。这个 null 结果来自 set 表示事务启动时密钥已存在,但未设置(因为 NX 标志)。
从redis文档:
如果由于用户指定了nx或xx选项但不满足条件而未执行set操作,则返回null批量回复

相关问题