事务例子_Redis事务系列之一Redis事务详解
一、前言
本章是redis事务系列知识第一章,redis事务系列主要讲解以下内容:
redis 事务
redis乐观锁讲解
redis乐观锁实现秒杀
我们一步一步来,本章主要讲解事务。
二、事务
2.1事务阐述
讲redis事务之前,我们先来看看事务的定义。
事务:一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
但redis的事务不并不是完整意义上的事务,我们称之为弱事务,为什么这么说呢?
redis中并没有回滚这种机制,也就是说,在一个事务中,中间一条命令执行失败,并不会导致前面已经执行的指令回滚。也不会造成后续的指令不做。我会在下面画图验证不支持回滚。
2.2 事务命令讲解
事务的命令一共就五条,为了方便大家记忆,我们先记住下面三条命令,:
1.开启事务:MULTI
2.执行事务:EXEC
3.取消事务:DISCARD
就像mysql中用begin开启事务、用commit结束事务一样。redis中是用multi开启事务,用exec执行命令。如果在exec之前你不想执行事务了,可以用discard取消当前事务。下面我们举例说明:
开启事务和执行事务的例子
> multi //开启事务> set s1 aaa > set s2 bbb> exec //执行事务> get s1 // 获取s1的值"aaa"> get s2 // 获取s2的值"bbb"
开启事务和取消事务的例子
> multi //开启事务> set s3 222 > discard //结束事务OK> exec //因为事务已经在上面取消了,所以在这里执行事务会报错。(error) ERR EXEC without MULTI> get s3 //事务被取消了,所以这里s3根本就没有值(nil)
2.3 事务为什么不支持回滚
讲解“事务为什么不支持回滚”之前我们先来汇总一下redis事务执行异常的几种情况,然后再总结事务为什么不支持回滚。
语法错误导致事务执行异常,该事务取消
在开启事务后,修改h1值为11111,h2值为2222,但h2语法错误,最终导致事务提交失败,h1、h2保留原值。
> set h1 11> set h2 22> multi //开启事务> set h1 11111> sets h2 2222 // 语法错误,下面报错(error) ERR unknown command `sets`, with args beginning with: `h2`, `2222`,127.0.0.1:6379> exec //执行事务,因为前面有语法错误,所以此事务取消(error) EXECABORT Transaction discarded because of previous errors.> get h1 // h1和h2的值并没有在事务中改变"11"> get h2"22"
2.运行时错误(Redis类型错误)导致事务异常
在开启事务后,修改s1值为1111111,s2值为2222222,但将s2的类型作为List,在运行时检测类型错误,最终导致事务提交失败,此时事务并没有回滚,而是跳过错误命令继续执行, 结果s1值改变、s2保留原值。
> set s1 11> set s2 22> multi> set s1 1111111> lpush s2 2222222 //此处类型错误,s2的类型是字符传,但我们把S2的类型作为List提交> exec //提交执行事务报错。1) OK2) (error) WRONGTYPE Operation against a key holding the wrong kind of value> get s1 //s1的值修改成功"1111111"> get s2 //s1的值修改失败"22"
总结:为什么Redis不支持事务回滚?
以上两个例子总结出,多数事务失败是由语法错误或者数据结构类型错误导致的,语法错误说明在命令入队前就进行检测的,而类型错误是在执行时检测的,Redis为提升性能而采用这种简单的事务,这是不同于关系型数据库的,特别要注意区分。
2.4 watch和unwatch命令讲解
2.4.1 watch命令
上面我们讲到redis是的事务是不支持回滚的,但是我们一定要让它回滚怎么办呢?这就需要用的watch命令了。
watch使用要注意:watch在mutil命令之前使用.
watch的作用是:监控一个值是否发生变化,如果没发生改变,它会执行事务队列中的命令,提交事务;如果发生变化,将不会执行事务中的任何命令,同时事务回滚。最后无论是否回滚,Redis都会取消执行事务前的WATCH命令。
这么说不太好理解,我们画图表示一下:
下面我们用代码验证一下,场景如下:
在事务开始前用WATCH监控a1,之后修改a1为c1111,MULTI开始事务,修改a2为c2222,执行EXEC,返回nil,说明事务回滚;查看下a2的值都没有被事务中的命令所改变。
代码如下:
//先设置2个值,我们用监控a1,然后用a2判断是否发生的回滚。127.0.0.1:6379> set a1 1111127.0.0.1:6379> set a2 2222127.0.0.1:6379> watch a1 //监听a1127.0.0.1:6379> set a1 c1111 // a1的值在监控后发生了改变。127.0.0.1:6379> multi //开始事务127.0.0.1:6379> set a2 c2222 //设置a2的值127.0.0.1:6379> exec //执行事务,发生错误,事务回滚(nil)127.0.0.1:6379> get a2 //a2的值并没有被更改,依旧是2222"2222"
2.4.2 unwatch命令
unwatch命令是取消监控,这里就不过多介绍了,下面是代码:
> set k1 1111> set k2 2222> WATCH k1> set k1 11 //改变k1的值> UNWATCH //取消监控> MULTI //开启事务> set k1 12> set k2 22> exec //执行事务成功了1) OK2) OK> get k1"12"> get k2"22"
三、结尾
好了,就讲到这里吧,这一章虽然知识点不多,但是小编为了更加通俗地讲出来也想了2、3天。
码字不易,希望大家关注一下小编,感谢!
有什么问题或者意见,大家可以提出来。
大家帮忙关注一下我微信公众号。关注后我有上百套学习资料和视频课程赠送。
事务例子_Redis事务系列之一Redis事务详解相关推荐
- python操作redis set_Python操作redis学习系列之(集合)set,redis set详解 (六)
#-*- coding: utf-8 -*- importredis r= redis.Redis(host="126.56.74.190",port=639,password=& ...
- Redis命令详解:Hashs
Hash是一种String类型的field.value的映射表,因此,它非常适合存储对象.下面我们来一一介绍与Hash相关的命令. HDEL 最早可用版本:2.0.0 时间复杂度:O(N),其中N为要 ...
- redis 数据类型详解 以及 redis适用场景场合
redis 数据类型详解 以及 redis适用场景场合 1. MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访 ...
- Redis主从复制详解(入门教程)
文章目录 概念 环境配置 一主二从 配置 测试 复制原理 哨兵模式 概述 测试 哨兵模式全部配置 以下是Redis相关笔记总结,方便自己以后复习,同时也希望对大家有所帮助. 内容 地址链接 Redis ...
- Spring和Redis整合详解
Spring和Redis整合详解 官方主页 Spring Spring Redis 概述 Redis是一个开源(BSD许可)的内存数据结构存储,用作数据库,缓存和消息代理. 简单来说,它是一个以(ke ...
- redis数据结构详解之Hash(四)
原文:redis数据结构详解之Hash(四) 序言 Hash数据结构累似c#中的dictionary,大家对数组应该比较了解,数组是通过索引快速定位到指定元素的,无论是访问数组的第一个元素还是最后一个 ...
- RxJS 系列之二 - Observable 详解
查看新版教程,请访问前端修仙之路 RxJS 系列目录 RxJS 系列之一 - Functional Programming 简介 RxJS 系列之二 - Observable 详解 (本文) RxJS ...
- Redis数据结构详解之Zset(五)
原文:Redis数据结构详解之Zset(五) 序言 Zset跟Set之间可以有并集运算,因为他们存储的数据字符串集合,不能有一样的成员出现在一个zset中,但是为什么有了set还要有zset呢?zse ...
- Redis命令详解:Connection
最近在学习Redis的相关知识,上一篇我们也介绍了Redis的安装方法和基本数据结构,后面就打算开一个新的系列文章:Redis命令详解.既是对基础的巩固,也是为了以后查询起来更方便. 整个系列会分为以 ...
- 并发编程系列之volatile关键字详解
并发编程系列之volatile关键字详解 1.volatile是什么? 首先简单说一下,volatile是什么?volatile是Java中的一个关键字,也是一种同步机制.volatile为了保证变量 ...
最新文章
- 1001 A+B Format
- 复现经典:《统计学习方法》​第 11 章 条件随机场
- 前端学习(1750):前端调试值之call stack
- table固定表头滚动
- LLE(局部线性嵌入)matlab代码实现
- 【LeetCode】剑指 Offer 06. 从尾到头打印链表
- Android 获取联系人的公司,android-如何从设备的联系人列表中获取用户...
- 为什么 CSS 这么难学?
- this.$router.push相关的vue-router的导航方法
- mysql repair 索引_MySQ索引操作命令总结(创建、重建、查询和删除索引命令详解)...
- python之collections模块Counter类使用学习
- BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]
- Emmet的高级功能与使用技巧
- Notebook左侧开启导航
- 4.0版本的wed.xml。 中间的部分是配置springMVC的。
- GitHub 标星 2.9w+,我发现了一个宝藏项目,作为编程新手有福了!
- GXOI/GZOI2019题解
- 2021-05-02 收心继续
- 简单个人静态HTML网页设计作品 基于HTML+CSS+JavaScript仿小米手机网站 html静态在线购物商城网页制作
- java线上培训机构排名前十,重要概念一网打尽!
热门文章
- boost::statechart::in_state_reaction相关的测试程序
- boost::range模块reversed相关的测试程序
- boost::mp11::mp_assign相关用法的测试程序
- boost::intrusive::set用法的测试程序
- boost::fusion::pair用法的测试程序
- boost::function_types::has_property_tag用法的测试程序
- GDCM:gdcm::ModuleEntry的测试程序
- ITK:计算曲率各向异性扩散
- VTK:PolyData之RemoveVertices
- VTK:绘图之HistogramBarChart