redis支持事务吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis支持事务吗相关的知识,希望对你有一定的参考价值。

参考技术A redis对事物是半支持
下面看一下Redis对事务错误处理
如果一个事务中的某个命令执行出错,Redis会怎样处理呢?要回答这个问题,首先要搞清楚是什么原因导致命令执行出错:
语法错误 就像上面的例子一样,语法错误表示命令不存在或者参数错误
这种情况需要区分Redis的版本,Redis 2.6.5之前的版本会忽略错误的命令,执行其他正确的命令,2.6.5之后的版本会忽略这个事务中的所有命令,都不执行,就比如上面的例子(使用的Redis版本是2.8的)
运行错误 运行错误表示命令在执行过程中出现错误,比如用GET命令获取一个散列表类型的键值。
这种错误在命令执行之前Redis是无法发现的,所以在事务里这样的命令会被Redis接受并执行。如果食物里有一条命令执行错误,其他命令依旧会执行(包括出错之后的命令)。比如下例:
Redis中的事务并没有关系型数据库中的事务回滚(rollback)功能,因此使用者必须自己收拾剩下的烂摊子。不过由于Redis不支持事务回滚功能,这也使得Redis的事务简洁快速。

Redis有事务冲突吗

1、写在前面

最近在看尚硅谷的Redis视频,里面的老师说到了事务冲突,我寻思Redis是单线程的,而且事务还有隔离性,哪来的事务冲突,于是上网搜答案,结果清一色复制粘贴,最后在看官网文档后才想明白这个问题,结论就是Redis没有事务冲突
注:本文不适合没了解过Redis事务的人阅读

2、Redis事务

有三个阶段:

  • 开始事务(MULTI)
  • 命令入队
  • 执行事务(EXEC)/ 取消事务(DISCARD)

有两个保证:

  • 事务中的所有命令都将被串行执行,事务执行过程中,Redis不会接收其它客户端发送的请求
  • 服务器如果在接收到EXEC命令前丢失了客户端连接,那么事务中的所有命令都不会被执行,如果接收到了EXEC命令,那么事务中的所有命令都会被执行。

有两种错误:

  • 入队异常 -> 所有命令都不会被执行
  • 执行异常 -> 除了异常命令外的其它命令都会继续执行

3、WATCH命令

WATCH命令为事务提供CAS(check-and-set),当两个事务产生资源竞争的时候,可以用WATCH对资源进行监控,如果资源发生变化,则取消执行当前事务。下面为大家举个例子说明,假如我们要将钱包里的钱扣减1000(myMoney表示钱包里的钱,初始值假设为1500),那么我们可以使用下面这个命令:

DECRBY myMoney 1000

然后我们会发现上面这个命令执行两次及以上时,myMoney就会变成负数,因此需要先将myMoney值取出来,判断大于等于1000后再进行扣减:

val = GET myMoney
if val >= 1000:
    DECRBY myMoney 1000

上述命令分了三个步骤(取值、判断、扣减),如果两个客户端同时进行请求,会导致第二个请求执行执行到判断语句时,val还是1500,但是在执行扣减语句时,val已经变成500了,所以要用WATCH命令对myMoney进行监控:

WATCH myMoney
val = GET myMoney
if val >= 1000:
    MULTI
    DECRBY myMoney 1000
    EXEC

上述代码都是伪代码,就是为了说明WATCH怎么跟事务搭配着用。

4、写在后面

其实根据第二节的两个保证,就可以很明确的看出来Redis是没有事务冲突的,因为Redis的两个事务是不可能同时执行的

那为什么要讲WATCH命令呢?

这是由于很多博客都在说因为Redis有事务冲突,所以要用到这个WATCH命令,这里我认为是他们讲错了,实际上是因为两个事务之间会有资源竞争,我认为的事务冲突是两个事务的命令会交叉着执行。

有什么不对的地方请指正!

以上是关于redis支持事务吗的主要内容,如果未能解决你的问题,请参考以下文章

不支持原子性的 Redis 事务也叫事务吗?

了解redis事务的cas操作吗

Spring事件机制支持事务吗

golang redis事务 --- 2022-04-03

Redis:对比一下Redis和MySQL的事务

Redis:对比一下Redis和MySQL的事务