在watch
中使用multi
的redis事务如下:
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
时,exec
命令中的res
就是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的最终数据中看到,这确实完成了除了set操作之外的所有hset
操作,这让我想知道一个事务怎么可能是部分的?
是什么原因导致了部分交易,它是如何发生的?有没有办法防止这种部分交易的发生?
我不认为这是部分事务问题。来自set
的null
结果意味着在事务开始时密钥已经存在并且没有被设置(因为NX
标志(。
来自redis文档:
如果由于用户指定了NX或XX选项而未执行SET操作,但条件不满足,则返回Null批量回复