Redis事务(4)

news/2024/10/31 7:33:10/

作者简介:码上言


代表教程:Spring Boot + vue-element 开发个人博客项目实战教程


专栏内容:个人博客系统


我的文档网站:http://xyhwh-nav.cn/

文章目录

  • Redis事务
    • 1、Redis事务概念
    • 2、应用
      • 1、MULTI开启事务
      • 2、事务失败处理
      • 3、Redis为什么不支持事务回滚?
      • 4、EXEC执行事务
      • 5、DISCARD取消事务
      • 6、WATCH监视key
      • 7、UNWATCH取消监视所有key

Redis事务

1、Redis事务概念

Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。

Redis事务没有隔离级别的概念:

批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行!

Redis不保证原子性:

Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。

收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务。
  • 命令入队。
  • 执行事务。

Redis事务相关命令:

  • MULTI :开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令系列。
  • EXEC:执行事务中的所有操作命令。( 一旦执行exec后,之前加的监控锁都会被取消掉 )
  • DISCARD:取消事务,放弃执行事务块中的所有命令。
  • WATCH key1 key2 …:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。
  • UNWATCH:取消WATCH对所有key的监视。

2、应用

1、MULTI开启事务

(1) 给k1、k2分别赋值,在事务中修改k1、k2,执行事务后,查看k1、k2值都被修改。

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 11
QUEUED
127.0.0.1:6379> set k2 22
QUEUED
127.0.0.1:6379> EXEC   // 或者选择取消事务DISCARD
1) OK
2) OK
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> get k2
"22"

2、事务失败处理

  • 若在事务队列中存在命令性错误(类似于java编译性错误),则执行EXEC命令时,所有命令都不会执行。

例如:在开启事务后,修改k1值为11,k2值为22,但k2语法错误,最终导致事务提交失败,k1、k2保留原值。

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 11
QUEUED
127.0.0.1:6379> setss k2 22
(error) ERR unknown command `setss`, with args beginning with: `k2`, `22`,
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379>
  • 若在事务队列中存在语法性错误(类似于java的1/0的运行时异常),则执行EXEC命令时,其他正确 命令会被执行,错误命令抛出异常。

例如:在开启事务后,修改k1值为11,k2值为22,但将k2的类型作为List,在运行时检测类型错误,最终导致事务提交失败,此时事务并没有回滚,而是跳过错误命令继续执行, 结果k1值改变、k2保留原值。

127.0.0.1:6379> set k1 v2
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 11
QUEUED
127.0.0.1:6379> lpush k2 22
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379>

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

多数事务失败是由语法错误或者数据结构类型错误导致的,语法错误说明在命令入队前就进行检测的,而类型错误是在执行时检测的,Redis为提升性能而采用这种简单的事务,这是不同于关系型数据库的,特别要注意区分。

4、EXEC执行事务

必须与MULTI命令成对使用

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
127.0.0.1:6379>

5、DISCARD取消事务

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379>

6、WATCH监视key

Redis的命令是原子性的,而事务是非原子性的,我们要让Redis事务完全具有事务回滚的能力,需要借助于命令WATCH来实现。

Redis使用WATCH命令来决定事务是继续执行还是回滚,那就需要在MULTI之前使用WATCH来监控某些键值对,然后使用MULTI命令来开启事务,执行对数据结构操作的各种命令,此时这些命令入队列。

当使用EXEC执行事务时,首先会比对WATCH所监控的键值对,如果没发生改变,它会执行事务队列中的命令,提交事务;如果发生变化,将不会执行事务中的任何命令,同时事务回滚。当然无论是否回滚,Redis都会取消执行事务前的WATCH命令。

111

事务,修改k1值为12,k2为22,执行EXEC,发回nil,说明事务回滚;查看下k1、k2的值都没有被事务中的命令所改变。

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> WATCH k1
OK
127.0.0.1:6379> set k1 11
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 22
QUEUED
127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379>

watch指令类似于乐观锁,在事务提交时,如果watch监控的多个KEY中任何KEY的值已经被其他客户端 更改,则使用EXEC执行事务时,事务队列将不会被执行,同时返回Nullmulti-bulk应答以通知调用者事 务执行失败。

7、UNWATCH取消监视所有key

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> WATCH k1
OK
127.0.0.1:6379> set k1 v11
OK
127.0.0.1:6379> UNWATCH
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 11
QUEUED
127.0.0.1:6379> set k2 22
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> get k2
"22"
127.0.0.1:6379>

http://www.ppmy.cn/news/945118.html

相关文章

Android 逆向助手 使用教程

下载逆向助手。将需要编译的apk文件copy到逆向助手的apktool目录,并CD到当前目录下。在cmd命令行中输入命令 apktool d -f 应用程序名,如:apktool d -f ZaiNa_V4.1.3.3_20180912_release.apk,回车后显示:可以看到&am…

怎么简单刷机?安卓刷机的使用教程

在很多人的眼中,都觉得刷机似乎是一件很复杂的事情,其实不然,传统的刷机方法是用户根据网上发布的教程进行刷机,由于过程不可控因素很多,的确有刷机变砖的风险,但是随着安卓智能手机的发展,国内…

安卓刷机之pixel

刷机记录: 提示:本例子是pixel sailfish: 刷rom 提示:刷rom及刷容比较简单一点: 1.首先去谷歌的官网去下载手机对应的机型; 2.下载刷机工具platform-tools.zip(github地址好像404了&#xf…

android 防刷机

最近做的一款产品,由于前期失误使用的是 官方的testkey 签名rom包。所以别人rom可以随意刷我们产品盒子,为了改正这个bug我们使用了新的签名刷自己产品。防止别人盗刷我们盒子。 要用新签名rom包,先要理解android升级原理, 第一…

ADB自动化线刷升级安卓车机版本

实现功能: 1.从FTP下载最新线刷包。 2.检测adb连接是否正常。 3.进行adb root 4.push_file()把本地升级包EP40_IMAGES_ALL.zip推送到/data/update/temp/目录下。 5.用updatecmd()升级/data/update/temp/目录下的EP40_IMAGES_ALL.zip升级包。 获取最…

安卓刷机教程

#wmd-preview h1 { color: #0077bb; /* 将标题改为蓝色 */ } 安卓刷机教程 1. 刷入第三方recovery 【根据手机型号下载recovery】 1.按住关机键及音量下键进入fastboot模式 2.手机连接电脑 3.使用附件【一键刷入recovery】中的工具点击一键刷入recovery 3.根据弹出窗口提示刷…

Android刷机

这里也有一篇比较详细的 http://blog.csdn.net/qq1084283172/article/details/52334452 官网刷机包 https://developers.google.com/android/images#hammerhead 我的机器是Nexus 5 一. 安装驱动 如何进入fastboot模式 1. 拔掉数据线,将手机关机 2. 关机…

安卓逆向——刷机

安卓刷机 刷机 :https://blog.csdn.net/a740169405/article/details/81103869 Edxposed :https://sspai.com/post/63094 全局调试 :https://www.cnblogs.com/codex/p/12250647.html lineageos :https://download.lineageos.org/…