node.js - nodejs并发下如何正确使用redis的GET SET命令?

标签 node.js redis

在我的并发项目中,我需要在redis中获取一个值,然后更新它并在redis中设置。像下面的代码,我期望的结果应该是3000,但是我无法得到正确的结果。顺序可能不对,可能是GET GET SET SET 或GET SET SET GET 等。如何才能得到正确的顺序和正确的结果?我应该使用一些锁吗?

import * as redis from 'redis';

let config: redis.ClientOpts = {
    host: '127.0.0.1',
    port: 6379
};

let redisClient: redis.RedisClient = new redis.RedisClient(config);
redisClient.set('num', '0');

(async () => {
    for (let i = 0; i < 1000; i++) {
        await add ();
    }
})();

(async () => {
    for (let i = 0; i < 1000; i++) {
        await add ();
    }
})();

(async () => {
    for (let i = 0; i < 1000; i++) {
        await add ();
    }
})();

// I know incr command, this is just an example.
async function add () { 
    let numStr: string = await get('num');
    let num: number = Number(numStr);
    num++;
    await set('num', String(num));
    console.log(num);
}

async function get (key: string): Promise<string> {
    return new Promise<string>((resovle, reject) => {
        redisClient.get(key, (err: Error, reply: string) => {
            if (err) {
                console.error(err);
                reject(err);
            }
            resovle(reply);
        })
    });
}

async function set (key: string, value: string): Promise<string> {  
    return new Promise<string>((resovle, reject) => {
        redisClient.set(key, value, (err: Error, reply: string) => {
            if (err) {
                console.error(err);
                reject(err);
            }
            resovle(reply);
        })
    });
}

最佳答案

Redis 提供了一种更灵活的方式来使用 MULTI-EXEC 方法“原子地”执行事务。

假设您正在处理一个银行系统,一位客户请求进行货币转账。您需要先从客户账户中打折,然后再存入另一个账户。在这些操作之间,其中一个可能会失败。所以,我们使用交易。

事务是原子的,这意味着所有操作要么全部发生,要么全部不发生。数据库具有锁定和并发管理实现,可确保发生这种情况,同时不会显着影响系统性能。

例子:

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

async function add () { 
    multi = client.multi();
    let numStr: string = await multi.get('num');
    let num: number = Number(numStr);
    num++;
    await multi.set('num', String(num));
    multi.exec(function (err, replies) {
        console.log(replies);});
    }
}

关于node.js - nodejs并发下如何正确使用redis的GET SET命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50628429/

相关文章:

node.js - 将 async/await 与 setTimeout 函数结合起来

node.js - 从控制台在文件资源管理器中打开目录并将焦点返回到控制台

javascript - 在 ejs 中制作类似组件的元素

php - Nodejs 和一些更基本的问题

javascript - Angular/在一个命令中创建一个没有 css 文件的模块,组件?

redis - 与按范围排序的 redis 相交的单个命令

node.js - 设置 node.js 数据库 MongoDB/Redis 的最佳方式?

mysql - Redis位图数据转Mysql——ETL策略

python - 我应该如何为 Django Channels 2.0 配置 Redis?

node.js - Node js、socket.io、redis 和 pm2