前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >nodejs操作Redis事务

nodejs操作Redis事务

作者头像
OECOM
发布于 2020-07-01 09:03:45
发布于 2020-07-01 09:03:45
1.4K00
代码可运行
举报
文章被收录于专栏:OECOMOECOM
运行总次数:0
代码可运行

有时候为了同时处理多个结构,我们需要向redis发送多个命令,或者服务器采用负载均衡的模式,多个负载同时访问redis,造成并发。为了让redis执行期间不受其他命令的影响,redis提供了事务的命令,事务在关系型数据库如mysql中很常见,也是为了应对并发等来产生的。

Redis的基本事务需要用到MULTI命令和exec命令,这种事务可以让一个客户端在不被其他客户端打断的情况下执行多个命令。和关系数据库那种可以在执行的过程中进行回滚的事务不同,在Redis里面,被multi命令和exec命令包围的所有命令会一个接一个的执行,知道所有的命令都执行完毕为止。当一个事务执行完毕之后,Redis才会处理其他客户端的命令。

要在redis里面执行事务,我们优先需要执行multi命令,然后输入我们想要在事务里面执行的命令,最后在执行EXEC命令。当Redis从一个客户端那里接收到multi命令时,redis会将这个客户端之后发送的所有命令都放入一个队列里面,知道这个客户端发送exec命令为止,然后redis就会在不被打断的情况下,一个接一个的执行存储在队列里面的命令。

在redis事务中,最常用的是multi命令和exec命令,下面来看一想redis事务的相关命令

命令

描述

DISCARD

取消事务,放弃执行事务块内的所有命令。

EXEC

执行所有事务块内的命令。

MULTI

标记一个事务块的开始。

UNWATCH

取消 WATCH 命令对所有 key 的监视。

WATCH key [key ...]

监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

下面来看一下命令行如何使用

很简单的是一个使用方法,下面再来看一下在nodejs中如何使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
redis事务
*/
router.get("/redisThing",function(req,res){
    var data = req.query.data;
    myRedis.client.multi([
        ["set", "ttt_1", "1111111"],
        ["incr", "ttt_1"],
        ["set", "ttt_3","hese"],
        ["get", "ttt_1"]
    ]).exec(function(err,result){
        console.log("第一个redis命令执行完成");
    });
    myRedis.client.multi([
        ["set", "ttt_1", "1111114"],
        ["incr", "ttt_1"],
        ["set", "ttt_3","hahaha"],
        ["get", "ttt_1"]
    ]).exec(function(err,result){

        console.log("第二个redis命令执行完成");
        if(!err){
            res.json(result)
        }else{
            res.json(err)
        }
    });
})

上面的代码是在正常的执行一次事务,这里的前提是正常执行,但是如果命令执行过程中失败了会有什么效果呢,我们看一下下图

从上图中,我们可以看到,redis命令即使中间有失败的,后续命令依然会继续执行,这就感觉有点坑爹了,按照关系型数据库的事务来说,这种情况应该回滚的,但是很遗憾,redis没有回滚。

其主要原因在于单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

除此之外,还有一件事使我们需要知道的,接着来看下图

上图中,我是先开了左侧的客户端事务,在提交exec之前又开了右侧的事务,然后将右侧的事务进行exec提交执行,然后再提交执行左侧的事务,我们发现,最终的执行结果是以左侧为准,也就是说,redis在整体提交以后才会进行阻塞其他客户端的操作,先提交exec的先执行。

说到这里,我想应该会有一个担心就是当我从redis从获取数据,进行判断以后得出相应的事务命令组合进行执行,但是我刚刚判断完成,其他的客户端又将该值进行了修改,那么我再修改就会产生问题,比如说商品数量,会出现负数的情况。对于这种情况,就需要用到watch命令了,在提交事务之前对需要修改的key进行watch,如果在这段时间内key值变化了,那么就会打断事务的执行。

来看一下上图,我在左侧先对name进行watch,然后multi命令,在执行exec之前,我在第二个也就是右侧的客户端对name执行了set命令,之后在左侧执行exec命令,我们发现左侧的exec命令返回了nil,其结果就是事务执行失败,没有进行任何的修改。

在nodejs中我们来进行一次测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
router.get("/redisThing",function(req,res){
    var data = req.query.data;
    myRedis.client.watch(["ttt_1","ttt_3"])
    setTimeout(function(){
        myRedis.client.multi([
            ["set", "ttt_1", "1111111"],
            ["incr", "ttt_1"],
            ["set", "ttt_3","hese"],
            ["get", "ttt_1"]
        ]).exec(function(err,result){
            if(!err){
                res.json(result)
            }else{
                res.json(err)
            }
            console.log("第一个redis命令执行完成");
        });
    },10000);
})

上面代码中给了10秒的延迟,以方便watch后在开一个客户端进行set修改,模拟watch后key被其他客户端修改的情况,执行后我们发现返回的是null,事务没有执行。至此我们解决了因其他客户端修改造成的数据错乱问题。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-10-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【玩转Redis面试第2讲】面试官再问Redis事务把这篇文章扔给他
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
爱笑的架构师
2020/09/24
7560
【玩转Redis面试第2讲】面试官再问Redis事务把这篇文章扔给他
Redis之事务解读
Redis Multi 命令用于标记一个事务块的开始。事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。
一个风轻云淡
2023/10/15
2110
可能会让你对Redis的事务有所了解
Redis 事务可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。Redis 的事务在形式上看起来也差不多,分为三个阶段
程序员小明
2021/10/13
5060
你真的懂Redis事务吗?
MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务的基础。
Bug开发工程师
2018/08/17
8.3K1
Redis事务机制
Redis 的事务提供了一种将多个命令请求打包,然后一次性、顺序地执行的能力。这种机制可以确保在事务执行过程中,不会被其他客户端的命令请求所打断,保证了事务的原子性。
栗筝i
2023/10/16
3560
Redis从入门到放弃(5):事务
悲观锁是一种对数据修改持有悲观态度的并发控制方式。它总是假设最坏的情况,每次读取数据时都默认其他线程会更改数据,因此需要加锁操作。
夕阳也是醉了
2023/10/16
2120
Redis从入门到放弃(5):事务
Redis事务与乐观锁
Redis 事务是一种将多个命令打包在一起执行的机制。通过使用事务,可以确保一系列命令在一次执行中依次执行,而不会被其他客户端的命令请求打断。
Andromeda
2024/01/05
2530
redis演练(3) redis事务管理
redis与memcached对比,redis不仅适合做缓存,而且可以做存储,这就有点数据库的影子了。说到数据库,事务是一个很重要的一个方面。
py3study
2020/01/07
4530
Redis事务
和其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制。在Redis中,MULIT,EXEC,DISCARD,WATCH这个四个命令是实现事务的基石,Redis中事务的实现特征
莫问今朝
2018/08/31
7280
Redis事务
【Redis07】事务
redis事务就是一个命令执行的队列,将一系列预定义的命令包装成一个整体,在执行时,就按这个顺序依次执行,中间不会被打断或干扰
JuneBao
2022/10/26
1490
Redis常用技术----事务
Redis的事务是使用MULTI-EXEC的命令组合,使用它可以提供两个重要的保证:
秃头哥编程
2019/06/11
4460
Redis常用技术----事务
Redis的事务机制
用于标记事务块的开启。MULTI执行之后,Redis会将后续的命令逐个放到一个缓存队列中,当EXEC命令被调用时,所有队列中的命令才会被原子化执行。
全栈程序员站长
2022/06/29
4620
Redis系列之事务机制
学习mysql数据库的时候,我们知道了事务的ACID特性,Redis也是支持事务的,不过和数据库的事务又有什么区别?在mysql数据库中,我们使用begin开启事务,提交是commit,回滚是rollback,然后Redis中的事务是怎么一回事?redis的事务其实可以看做是一组命令按照顺序,串行执行队列中的命令,其它客户端的命令不会写入到这个队列中。总的来说,redis事务就是一次性、顺序性、排他性的执行一个队列中的一组命令
SmileNicky
2023/12/18
1620
StackExchange.Redis学习笔记(四) 事务控制和Batch批量操作
Redis事物 Redis命令实现事务 Redis的事物包含在multi和exec(执行)或者discard(回滚)命令中 和sql事务不同的是,Redis调用Exec只是将所有的命令变成一个单元一起执行,期间不会插入其他的命令。 这种方式不保证事务的一致性,即使中间有一条命令出错了,其他命令仍然可以正常执行,并且无法回滚 下面的例子演示了一个基本的事务操作 127.0.0.1:6379> multi OK 127.0.0.1:6379> set name mike QUEUED 127.0.0.1:637
蓝夏
2018/05/02
1.3K0
StackExchange.Redis学习笔记(四) 事务控制和Batch批量操作
Redis 事务
事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。
三产
2022/05/11
4180
Redis 事务
以下是一个事务的例子,它先以MULTI开始一个事务,然后将多个命令入队到事务中,最后由EXEC命令触发事务,一并执行事务中的所有命令:
子润先生
2021/07/02
2730
redis事务
本文记录一些redis事务相关的原理。 1、基本概念 1)什么是redis的事务? 简单理解,可以认为redis事务是一些列redis命令的集合,并且有如下两个特点: a)事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 b)事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。 2)事务的性质ACID 一般来说,事务有四个性质称为ACID,分别是原子性,一致性,隔离性和持久性。 a)原子性atomicity:red
用户1225216
2018/03/05
6180
Redis中的事务介绍
MySQL中的事务大家都不陌生,Redis中的事务和MySQL中的事务不同,今天看下Redis事务中的一些知识点吧。
AsiaYe
2020/07/09
3590
Redis事务
Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。总结说:redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。
用户3876103
2024/08/28
1390
Redis的事务
标记一个事务块的开始。 事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。 返回值:总是返回 OK 。
别团等shy哥发育
2023/02/25
2190
Redis的事务
相关推荐
【玩转Redis面试第2讲】面试官再问Redis事务把这篇文章扔给他
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文