什么是redis?

Redis 是一个开源的,内存中的数据结构存储系统。

可以用作数据库、缓存和消息中间件。

什么是事务?

事务是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;

这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;

事务是一组不可再分割的操作集合(工作逻辑单元);

顺带提一下事务的四个特性:

A:原子性(Atomicity)

事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做

C:一致性(Consistency)

事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。

如果数据库系统运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。

I:隔离性(Isolation)

一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

D:持久性(Durability)

也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。

什么是Redis事务?

官网上给出的解释是:

事务可以一次执行多个命令,并且带有以下两个重要的保证:

1.事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

2.事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

EXEC 命令负责触发并执行事务中的所有命令:

如果客户端在使用 MULTI 开启了一个事务之后,却因为断线而没有成功执行 EXEC ,那么事务中的所有命令都不会被执行。

另一方面,如果客户端成功在开启事务之后执行 EXEC ,那么事务中的所有命令都会被执行。

这样看,好像和事务的解释是一致的,那么redis事务应该能满足事务的四个特性。

那么我们实际操作试一下。

第一组命令:

multiincr fooincr booexec

执行结果

第二组命令:

multiincr fooasdasdincr booexec

执行结果

(Another Redis客户端↓)

(Redis Desktop Manager客户端↓)

可以看出,在第三条命令中我随便打了几个字符,提交事务的时候并没有成功,符合我们对事务的理解,具有原子性。但是,有一个细节,那就是错误命令在我输入的时候就已经报错了(这块Another Redis客户端与Redis Desktop Manager客户端表现不一样,但结果是一样的,这个后续再说),也就是说这条错误命令在进入队列的时候redis就已经知道这是一条错误命令,这样,整个事务的命令将全部失败。

那么如果命令是正确的,但在执行时报错呢?

multiset foo aincr fooincr booexec

执行结果

(foo是字符串类型,再执行incr命令肯定不成功)

那么综上,我们在使用redis事务时可能会遇上以下两种错误:

1.事务在执行 EXEC 之前,入队的命令可能会出错。比如说,命令可能会产生语法错误(参数数量错误,参数名错误,等等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话)。

2.命令可能在 EXEC 调用之后失败。例如事务中的命令可能处理了错误类型的键,将列表命令用在了字符串键上面,诸如此类。

对于发生在 EXEC 执行之前的错误,客户端以前的做法是检查命令入队所得的返回值:如果命令入队时返回 QUEUED ,那么入队成功;否则,就是入队失败。如果有命令在入队时失败,那么大部分客户端都会停止并取消这个事务。(这相当于解释了两个客户端,对同一个错误语句,返回结果不同,说明是客户端自己控制的。)

下面这应该能是加分项

不过,从 Redis 2.6.5 开始,服务器会对命令入队失败的情况进行记录,并在客户端调用EXEC命令时,拒绝执行并自动放弃这个事务。在 Redis 2.6.5 以前, Redis 只执行事务中那些入队成功的命令,而忽略那些入队失败的命令。

那么回过头来看一下,Redis事务有没有满足事务的四个特性?

好像是没有。

那没有满足哪条呢?

有人可能说是原子性,但原子性的描述是“事务中包含的各操作要么都做,要么都不做”;不是“事务中包含的各操作要么都成功,要么都不做”。那么redis事务中的各项操作是不是都执行了?是。符合原子性描述吗?符合。只是有的没成功。那么没成功执行的操作结果也存在了数据库中,影响了什么?影响了事务的一致性。

也就是redis没有保证使数据库从一个一致性状态变到另一个一致性状态,也就是数据中不仅包含成功的结果,同时包含了失败的结果。

那么导致redis坚持了原子性,损害了一致性的问题根源在哪呢?

在于redis没有回滚这个东西。

为什么 Redis 不支持回滚(roll back)

官网给出的解释:

以下是这种做法的优点:

Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。

因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

有种观点认为 Redis 处理事务的做法会产生 bug , 然而需要注意的是, 在通常情况下, 回滚并不能解决编程错误带来的问题。 举个例子, 如果你本来想通过 INCR 命令将键的值加上 1 , 却不小心加上了 2 , 又或者对错误类型的键执行了 INCR , 回滚是没有办法处理这些情况的。

综上,我们需要记住的是两点:

1.即使事务中有某条/某些命令执行失败了, 事务队列中的其他命令仍然会继续执行 —— Redis 不会停止执行事务中的命令。

2. Redis 不支持回滚

完。

Redis事务能回滚吗?相关推荐

  1. 为什么 Redis 不支持回滚(roll back)

    为什么 Redis 不支持回滚(roll back) 如果你有使用关系式数据库的经验, 那么 "Redis 在事务失败时不进行回滚,而是继续执行余下的命令"这种做法可能会让你觉得有 ...

  2. 【node】express中mysql的基本用法、连接池的使用、事务的回滚

    [node]express中mysql的基本用法.连接池的使用 安装mysql包 mysql的配置信息 mysql基本操作 查询mysql并渲染数据 mysql插入操作 首先在html页面写上< ...

  3. spring@Transactional注解事务不回滚不起作用无效的问题处理

    这几天在项目里面发现我使用@Transactional注解事务之后,抛了异常居然不回滚.后来终于找到了原因. 如果你也出现了这种情况,可以从下面开始排查. 一.特性 先来了解一下@Transactio ...

  4. Spring事务异常回滚,try catch 捕获异常不回滚

    Spring事务异常回滚,try catch 捕获异常不回滚 参考文章: (1)Spring事务异常回滚,try catch 捕获异常不回滚 (2)https://www.cnblogs.com/GH ...

  5. Spring事务异常回滚,捕获异常不抛出就不会回滚

    Spring事务异常回滚,捕获异常不抛出就不会回滚 参考文章: (1)Spring事务异常回滚,捕获异常不抛出就不会回滚 (2)https://www.cnblogs.com/chen-lhx/p/6 ...

  6. 为什么catch了异常,但事务还是回滚了?

    前几天我发了这篇文章<我来出个题:这个事务会不会回滚?>(https://blog.didispace.com/will-this-transcation-rollback/) 得到了很多 ...

  7. springboot 事务手动回滚_Spring Boot中的事务是如何实现的

    1. 概述 一直在用SpringBoot中的@Transactional来做事务管理,但是很少想过SpringBoot是如何实现事务管理的,今天从源码入手,看看@Transactional是如何实现事 ...

  8. java 自定义异常 未回滚_抛出自定义异常,spring AOP事务不回滚的解决方案

    spring AOP 默认对RuntimeException()异常或是其子类进行事务回滚,也就是说 事务回滚:throw new RuntimeException("xxxxxxxxxxx ...

  9. 每日一博 - 常见的Spring事务失效事务不回滚案例集锦

    文章目录 事务不生效 方法内部调用 修复方法一 : [新加一个Service方法] 修复方法二:[在该Service类中注入自己] 修复方法三:[通过AopContent类]<---- 推荐 访 ...

最新文章

  1. FRVT赛程全纪录:格灵深瞳全球排名前五
  2. java打印文档_从Java应用程序打印文档?
  3. iis日志转到sql存储
  4. JavaScript禁用鼠标右键菜单
  5. 一对经典的时间获取客户/服务器程序
  6. 项目实战,平均负载过高,最后发现却是这个搞鬼
  7. 51Nod 1131 - 覆盖数字的数量(分类讨论)
  8. validation 开始日期 结束日期_Spring Boot集成validation用于优雅的校验API参数的合法性...
  9. 实验3:利用SVM实现线性高斯分类
  10. C++关键字(static/register/atuo/extern/volatile/const/inline/define/typedef)
  11. 英文论文如何进行润色?
  12. c++_十进制数-10的三进制4位补码是多少?
  13. 计算机用通讯电压多少,通信局(站)用交流电源的质量指标要求
  14. Pingouin: 基于pandas和numpy的统计包
  15. setoolkit进行钓鱼攻击
  16. 通过Python做葡萄酒成分与质量的关系分析并可视化--GBDT/随机森林特征选取
  17. 袁春风老师:计算机系统基础(一) 第一章
  18. UR机械臂学习(7-1):MoveIt简单编程实现机械臂运动(正逆运动学)
  19. 年薪60万+?这份10万字的面试突击宝典涵盖阿里 P5 工程师~P7 所有技术栈
  20. 6种优秀的浏览器兼容性测试工具

热门文章

  1. 【温故而知新-Javascript】理解 DOM
  2. 记一次查找投稿期刊的过程
  3. 关于Omnet++与NS-3的学习选择讨论(四)
  4. E667: Fsync failed
  5. 边缘计算需要java_一分钟快速了解边缘计算
  6. matplotlib——1. 常用功能汇总
  7. 申请工行信用卡的一点经历(答疑)
  8. 奥蓝网络科技温馨提示:企业做新闻营销不能忽略以下几点
  9. 在macOS中同时安装jdk8、jdk9、jdk11、jdk12并自由切换
  10. bootstrap row 下面的 col-md 高度相等 高度 一致 高度一样 有大用