我正在尝试在我的项目中调试一些
WatchErrors
,并注意到我们没有使用isolatedClient
,我想知道这是否是原因。我没有看到任何日志(或代码路径)表明被监视的键在被监视后被更改。
当我在事务中实际写入 Redis 时,我的代码基本上是这样的:
try {
await this.client.watch(key);
await this.client
.multi()
.hSet(key, some_value)
.expire(key, some_expiration)
.exec();
}
catch (e) {
if (e instanceof WatchError) {
// seeing this block get hit often
}
throw e;
}
我在node-redis自述文件中注意到,交易部分给出了一个示例,没有调用
.watch()
没有创建isolatedClient
。但是,在 does 调用 .watch()
的链接示例中,还使用 isolatedClient
方法额外创建了 executeIsolated
。
使用
isolatedClient
到底有什么影响?如果我们调用 .watch()
,我们是否需要使用其中之一?如果需要,为什么?如果 WatchError
和 .watch()
之间使用不同的连接,是否会抛出 .exec()
?
redis-server
在连接上存储 WATCH
状态,这意味着并发 WATCH
和 MULTI
/EXEC
将覆盖彼此的状态...在这种情况下,您需要有一个池连接数,每次需要 WATCH
时,从池中获取一个连接并使用它(这正是 executeIsolated
正在做的事情):
client.executeIsolated(async isolatedClient => {
await isolatedClient.watch(key);
await isolatedClient
.multi()
.hSet(key, some_value)
.expire(key, some_expiration)
.exec();
});
您可以通过将
isolationPoolOptions
选项传递给 createClient
来配置池行为:
createClient({
isolationPoolOptions: {
min: 1,
max: 100
}
});
请参阅 generic-pool 了解更多选项。