繁体   English   中英

如何在Node.js中使用Redis WATCH?

[英]How to use redis WATCH in Node.js?

背景

我有一个原子操作,我需要使用一个锁来防止其他客户端读取不稳定的值。

  • 平台 :节点10.1.0
  • 图书馆Redis

根据官方文档,解决方案是将WATCHMULTI一起使用:

问题

现在,已记录了MULTI的用法,我对如何使用它有了一个大致的了解。

var redis = require( "redis" );
var bluebird = require( "bluebird" );
var client = redis.createClient();
var multi = client.multi();

multi.hsetAsync( "test", "array", "[1, 2]" );
multi.hgetAsync( "test", "array" );
multi.execAsync( ).then( console.log ); // [ 0, "[1, 2]" ]

我了解这是multi的正确实现。 首先, 我需要创建一个客户端,然后创建一个多查询。

我知道multiclient共享相同的接口,但是也不清楚在multi查询中使用hgetAsync而不是hget有什么好处(因为有的话),因为我假设multi所做的全部就是将请求添加到同步排队(因此,我不需要Aart vartiant)。

调用multi.execAsync( )后,查询的执行将自动进行

但是我不知道WATCH应该如何进入这里。 我在文档中找不到对它的任何引用,也没有关于REDIS拥有的乐观锁系统的任何信息。

问题

所以我有以下问题:

  1. MULTI是否支持WATCH
  2. 如果是这样,您可以共享一个代码段吗?
  3. 在此示例中使用multi.hgetAsync( "test", "array" );是否有意义multi.hgetAsync( "test", "array" ); 而不是multi.hget( "test", "array" );

n

没有关于在节点redis中使用WATCH的文档。 但是,我确实在MDN中找到了一组非常有用的提示:

https://developer.mozilla.org/zh-CN/docs/Mozilla/Redis_Tips

总而言之,WATCH的用法如下:

var redis  = require("redis"),
client = redis.createClient({ ... });

client.watch("foo", function( err ){
    if(err) throw err;

    client.get("foo", function(err, result) {
        if(err) throw err;

        // Process result
        // Heavy and time consuming operation here

        client.multi()
            .set("foo", "some heavy computation")
            .exec(function(err, results) {

                /**
                 * If err is null, it means Redis successfully attempted 
                 * the operation.
                 */ 
                if(err) throw err;

                /**
                 * If results === null, it means that a concurrent client
                 * changed the key while we were processing it and thus 
                 * the execution of the MULTI command was not performed.
                 * 
                 * NOTICE: Failing an execution of MULTI is not considered
                 * an error. So you will have err === null and results === null
                 */

            });
    });
});

因此,回答我的问题:

  1. 是的,虽然watch是呼吁RedisClient原型,而不是在Multi原型。
  2. 上面提供的代码段。
  3. 由于具有Multi原型的对象中的每个方法都会返回对象本身,因此使用方法的Async版本不会带来任何好处,除了execAsync之外, execAsync允许您执行多查询并以Promise而不是Promise处理响应。打回来。

重要笔记

另一个真正重要的事情是, watch仅适用于KEYS, 而不适用于哈希 因此,就我而言,您无法观看哈希test的字段array 您可以观看整个test集,但不能观看特定的字段。

因此,因为在我的代码中,我实际上想监视哈希中的字段。 这是不可能的。 相反,我必须使用一个密钥命名系统来代替:

var redis = require( "redis" );
var bluebird = require( "bluebird" );
var client = redis.createClient();
var multi = client.multi();

client.watchAsync( "test_array" )
    then( ( ) =>
        multi.set( "test_array", "[1, 2]" )
            .get( "test_array" )
            .execAsync( ) 
    )
    .then( console.log ); // [ 0, "[1, 2]" ]

有关此文档的文档确实很少,但是我希望这个问题对将来的人有所帮助。


从未来开始阅读吗?

如果您日后阅读node_redis ,现在就可以享受我对node_redis项目的个人贡献并查看更新的文档:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM