为什么 Redis 的事务不支持回滚?

对于关系型数据库来说,事务这个面试的时候最开头的就是什么是事务?事务的ACID,事务的隔离级别,当说完可能就讲什么是MVCC机制了等等,

但是在Redis中的事务是没有原子性的,了解Redis的管道机制的小伙伴应该会知道,管道机制主要为了多次提交而发生的读写,通过批量的方式减少命令传输的次数,而Redis的事务就像管道机制提交的命令一样是提交的命令集合,

Redis事务的命令主要是 multi(开启事务) exec(执行事务) discard(丢弃事务)
当我们开启事务后就可以同时执行一组命令,根据顺序一个一个执行,执行成就会返回 QUEUED 看Redis返回的结果为什么会是一个队列意思呢?Redis把开启事务后的命令都存储到了Redis的事务队列里面了,当我们没有执行exec命令的时候这些命令都在队列里面,当执行了就会返回每条命令的执行结果,如图:
在这里插入图片描述

看到上面返回的是事务开启后里面命令的返回结果,执行成功就会输出每条命令的结果,失败就会返回 nil 取消就返回 OK
在开启事务需要注意地方:

  • 如果事务执行时 命令集合中存在命令的书写错误,那么整个集合的命令都不会被执行

    • 不过,从 Redis 2.6.5 开始,服务器会对命令入队失败的情况进行记录

    • 并在客户端调用 EXEC 命令时(事务执行命令),拒绝执行并自动放弃这个事务

    • 如参数数量错误、参数名错误等等,或者其他更严重的错误,比如内存不足

    • 对于这种情况,Redis早些时候会在事务执行前检查命令入队所得的返回值:如果命令入队时返回 QUEUED ,那么入队成功;否则,就是入队失败

    • 如果有命令在入队时失败,那么大部分客户端都会停止并取消这个事务

  • 如果命令编译通过,异常为运行时异常 那么其他的命令仍会照常执行,存在运行时异常的命令会执行失败

    • 比如使用incy命令对一个非整形数据进行原子 +1操作
  • 事务是可以取消的,如果事务取消 那么这些入队的命令也不会被执行

    • 可以手动使用命令取消,也可以直接 ctrl + F4强制取消(在事务未被执行前打断施法即可)

事务的取消:
当我们想取消事务的时候就可以使用 discard丢弃当前事务,这个命令要在exec前执行,因为redis没有回滚的概念。

阿里的一个面试:为什么Redis不支持回滚:

我们使用过关系型数据库的经验就认为,这面试啥呀?一个大大的疑问,而Redis没有回滚的优点:

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

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

Redis主要认为失败都是使用者造成的所以就没有回滚操作。

在Redis中除了没有原子性外,Redis对事务也没有隔离级别的概念,所以就不会产生我们使用关系型数据库需要关注的脏读,幻读,重复读的问题,

Redis的watch机制实现乐观锁

虽说 Redis不支持直接回滚,但我们可以通过 Redis提供的一个命令来实现回滚
这个命令就是 watch,该命令可以为 Redis事务提供 check-and-set (CAS)行为。
我们可以使用 watch命令来监视一个 或多个key,如果被监视的 key在事务执行前被修改过那么本次事务将会被取消,也就是所谓的回滚
只有确保被监视的 key,在事务开始前到执行 这段时间内未被修改过事务才会执行成功(类似乐观锁)
如果一次事务中存在被监视的 key,无论此次事务执行成功与否,该 key的监视都将会在执行后失效 也就是说监视是一次性的。
watch在事务的 运用注意点:
watch要在事务开启之前就监控不然会报错
watch是一次性的
watch开启的客户端端口连接这个客户端对watch的监听就会被取消

看watch的使用

在这里插入图片描述
客户端2

那就会有小伙伴有疑问那Redis的事务有什么用呢?

我认为现阶段Redis事务的作用不大,因为我们看上面的开启事务后每提交一次命令都返回 QUEUED ,所以我们在开启事务的时候会跟 Redis的管道一起使用来减少读写请求次数,而Redis的事务不保证原子性,隔离性,我们谈到什么Redis实现分布式锁的细节的时候就会说加锁时候要保证原子性,解锁的时候原子性也要保证,所以现阶段的Redis的事务原子性都不保证,我感觉作用不太大

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值