105. Python语言 的 项目前导(上) 之 Redis 第六章 :Redis 事务

56 篇文章 0 订阅
15 篇文章 0 订阅

本章主题

  

关键词

  

前言

  事务指的是提供一种将多个命令打包,一次性按顺序地执行的机制,并且保证服务器只有在执行完事务中的所有命令后,才会继续处理此客户端的其他命令。

  事务也是其他关系型数据库所必备的基础功能,以支付的场景为例,正常情况下只有正常消费完成之后,才会减去账户余额。但如果没有事务的保障,可能会发生消费失败了,但依旧会把账户的余额给扣减了,我想这种情况应该任何人都无法接受吧?所以事务是数据库中一项非常重要的基础功能。

  

事务基本使用

事务在其他语言中,一般分为以下三个阶段:

  • 开启事务——Begin Transaction

  • 执行业务代码,提交事务——Commit Transaction

  • 业务处理中出现异常,回滚事务——Rollback Transaction

Redis 中的事务从开始到结束也是要经历三个阶段:

  • 开启事务
  • 命令入列
  • 执行事务/放弃事务

  其中,开启事务使用 multi 命令,事务执行使用 exec 命令,放弃事务使用 discard 命令。

  

开启事务

multi 命令用于开启事务:

> multi
OK

multi 命令可以让客户端从非事务模式状态,变为事务模式状态。

  注意:multi 命令不能嵌套使用,如果已经开启了事务的情况下,再执行 multi 命令,会提示如下错误:

(error) ERR MULTI calls can not be nested

  执行效果,如下代码所示:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> multi
(error) ERR MULTI calls can not be nested

  当客户端是非事务状态时,使用 multi 命令,客户端会返回结果 OK,如果客户端已经是事务状态,再执行 multi 命令会 multi 命令不能嵌套的错误,但不会终止客户端为事务的状态

  

命令入列

  客户端进入事务状态之后,执行的所有常规 Redis 操作命令(非触发事务执行或放弃和导致入列异常的命令)会依次入列,命令入列成功后会返回 QUEUED,如下代码所示:

> multi
OK
> set k v
QUEUED
> get k
QUEUED

  注意:命令会按照先进先出(FIFO)的顺序出入列,也就是说事务会按照命令的入列顺序,从前往后依次执行。

  

执行事务/放弃事务

  执行事务的命令是 exec,放弃事务的命令是 discard。

执行事务

> multi
OK
> set k v2
QUEUED
> exec
1) OK
> get k
"v2"

  

放弃事务

> multi
OK
> set k v3
QUEUED
> discard
OK
> get k
"v2"

  

事务错误&回滚

事务执行中的错误分为以下三类:

  • 执行时才会出现的错误(简称:执行时错误);
  • 入列时错误,不会终止整个事务;
  • 入列时错误,会终止整个事务。

  

执行时错误

> get k
"v"
> multi
OK
> set k v2
QUEUED
> expire k 10s
QUEUED
> exec
1) OK
2) (error) ERR value is not an integer or out of range
> get k
"v2"

  

入列错误不会导致事务结束

> get k
"v"
> multi
OK
> set k v2
QUEUED
> multi
(error) ERR MULTI calls can not be nested
> exec
1) OK
> get k
"v2"

  

入列错误导致事务结束

> get k
"v2"
> multi
OK
> set k v3
QUEUED
> set k
(error) ERR wrong number of arguments for 'set' command
> exec
(error) EXECABORT Transaction discarded because of previous errors.
> get k
"v2"

  

为什么不支持事务回滚?

Redis 官方文档的解释如下

If you have a relational databases background, the fact that Redis commands can fail during a transaction, but still Redis will execute the rest of the transaction instead of rolling back, may look odd to you.
However there are good opinions for this behavior:
• Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.
• Redis is internally simplified and faster because it does not need the ability to roll back.
An argument against Redis point of view is that bugs happen, however it should be noted that in general the roll back does not save you from programming errors. For instance if a query increments a key by 2 instead of 1, or increments the wrong key, there is no way for a rollback mechanism to help. Given that no one can save the programmer from his or her errors, and that the kind of errors required for a Redis command to fail are unlikely to enter in production, we selected the simpler and faster approach of not supporting roll backs on errors.

大概的意思是,作者不支持事务回滚的原因有以下两个:

  • 他认为 Redis 事务的执行时,错误通常都是编程错误造成的,这种错误通常只会出现在开发环境中,而很少会在实际的生产环境中出现,所以他认为没有必要为 Redis 开发事务回滚功能;
  • 不支持事务回滚是因为这种复杂的功能和 Redis 追求的简单高效的设计主旨不符合。
    这里不支持事务回滚,指的是不支持运行时错误的事务回滚。

  

总结小便条

本篇文章主要讲了以下几点内容:

  1. 事务为多个命令提供一次性按顺序执行的机制,与 Redis 事务相关的命令有以下三个:
    1)multi:开启事务
    2)exec:执行事务
    3)discard:丢弃事务
  2. 正常情况下 Redis 事务分为三个阶段:开启事务命令入列执行事务

  

  本章回顾暂时就到这了,如果还有点晕,那就把文章里所有引用的案例代码再敲几遍吧。拜拜~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值