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

Fla*_*nix 0 javascript redis node.js node-redis

背景

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

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

根据官方文档,解决方案是与WATCH一起使用MULTI

问题

现在,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]" ]
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

问题

所以我有以下问题:

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

Fla*_*nix 6

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
                 */

            });
    });
});
Run Code Online (Sandbox Code Playgroud)

因此,回答我的问题:

  1. 是的,尽管watchRedisClient原型而不是原型上被调用Multi
  2. 上面提供的代码段。
  3. 因为具有Multi原型的对象中的每个方法都会返回对象本身,所以使用Async方法的版本不会带来任何好处,除了execAsync它使您可以执行多个查询并在Promise中处理响应而不是回调。

重要笔记

另一个真正重要的事情是watch仅适用于KEYS,而不适用于哈希。因此,就我而言,您无法查看arrayhash 的字段test。您可以观看整个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]" ]
Run Code Online (Sandbox Code Playgroud)

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


从未来开始阅读吗?

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