【Redis】Redis事务

news2024/9/22 5:40:28

介绍

  • 可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化, 按顺序地串行化执行而不会被其他命令插入
  • 一个队列中,一次性、顺序性、排他性的执行一系列命令
  • 没有隔离级别的概念,没有脏读、不可重复读等。

Redis事务和数据库事务

单独的隔离操作Redis的事务仅仅是保证事务里的操作会被连续独占的执行,redis命令执行是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的
没有隔离级别的概念因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了
不保证原子性Redis的事务不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
排它性Redis会保证一个事务内的命令依次执行,而不会被其它命令插入

基本操作

在这里插入图片描述

正常执行

MULTI #事务开始
EXEC #执行事务

示例

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> MULTI #事务开始
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> INCR count
QUEUED
127.0.0.1:6379(TX)> EXEC #执行事务
1) OK
2) OK
3) (integer) 1
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "count"

放弃事务

MULTI #事务开始
DISCARD #放弃事务

示例

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> DISCARD
OK
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "count"

全体连坐

在MULTI 和 EXEC 之间有一个指令语法错误,所有的命令都不会执行

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k3 33333
QUEUED
127.0.0.1:6379(TX)> set k4 44444
QUEUED
127.0.0.1:6379(TX)> set k5 #语法错误,无法编译通过
# 如果任何一个命令语法错误,Redis会直接返回错误,所有的命令都不会执行
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "count"

错误命令停止

  • Redis 不提供事务回滚的功能,开发者必须在事务执行出错后,自行恢复数据库状态
  • 注意和传统数据库事务区别,不一定要么一起成功要么一起失败
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k4 4444
QUEUED
127.0.0.1:6379(TX)> set email kkkkk@kkk.com
QUEUED
127.0.0.1:6379(TX)> INCR email #语法没有错误
QUEUED
127.0.0.1:6379(TX)> EXEC #执行事务
1) OK
2) OK
3) (error) ERR value is not an integer or out of range #报错,对的命令执行了,错误则没有执行,keys *中可以看到
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "count"
4) "k4"
5) "k3"
6) "email"

watch监控

Redis使用Watch 来提供乐观锁定,类似于 CAS(Check-and-Set)

  • 悲观锁
    • 认为每次去拿数据都很认为别人会修改,所以每次拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁
  • 乐观锁
    • 认为每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据
    • 策略:提交版本必须 大于 记录当前版本才能执行更新
  • CAS
    • check-and-set(JUC中CAS操作相似)

watch

初始化k1balance两个key,先监控,再开启MULTI,保证两个key变动在同一事务中。

正常执行(没有加塞和篡改
127.0.0.1:6379> get k1
"abc"
127.0.0.1:6379> get balance
"100"
127.0.0.1:6379> WATCH balance
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 abc2
QUEUED
127.0.0.1:6379(TX)> set balance 110
QUEUED
127.0.0.1:6379(TX)> get k1
QUEUED
127.0.0.1:6379(TX)> get balance
QUEUED
127.0.0.1:6379(TX)> EXEC
1) OK
2) OK
3) "abc2"
4) "110"
加塞和篡改

watch 命令是一种乐观锁的实现,Redis 在修改的时候会检测数据是否被更改,如果更改了,则执行失败。

1、监控当前的balance,并开启事务

127.0.0.1:6379> get balance
"110"
127.0.0.1:6379> WATCH balance
OK
127.0.0.1:6379> MULTI
OK

2、打开另一个客户端,修改balance的值(加塞篡改)

[root@192 myredis]# redis-server redis7.conf 
[root@192 myredis]# redis-cli -a 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> set balance 300
OK

3、在事务中修改balance的值,并执行事务

127.0.0.1:6379(TX)> set balance 200
QUEUED
127.0.0.1:6379(TX)> set k2 222
QUEUED
127.0.0.1:6379(TX)> EXEC
(nil)
127.0.0.1:6379> get balance
"300"

可见,当另一个客户端已经修改balance的值之后,再在监控后的事务中修改balance的值,会导致事务执行失败。因为数据已经被更改了。

unwatch

放弃对键值的监控

1、监控当前的balance

127.0.0.1:6379> WATCH balance
OK
127.0.0.1:6379> get balance
"300"

2、在另一个客户端中,修改balance的值

127.0.0.1:6379> set balance 400
OK
127.0.0.1:6379> get balance
"400"

3、放弃对balance的监控

127.0.0.1:6379> UNWATCH
OK

4、打开事务,修改balance的值,并执行事务

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set balance 500
QUEUED
127.0.0.1:6379(TX)> get balance
QUEUED
127.0.0.1:6379(TX)> EXEC
1) OK
2) "500"

小结

  • 一旦执行了 exec 之前加的watch监控锁都会被取消掉
  • 当客户端连接丢失的时候(比如退出连接),所有东西都会被取消监视

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/459056.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

思维导图从入门到大神

思维导图怎么做?思维导图是一种发散性思维的图。在我们生活的方方面面都有运用。无论是工作、学习、还是生活,我们都可以用到它。那思维导图是怎么绘制的呢?其实非常简单,只要这简单的几步 1、首先在绘制思维导图前,我…

veImageX 演进之路:iOS 高性能图片加载 SDK

动手点关注 干货不迷路 1. SDK简介 图片在业务应用场景是一个常见的元素,veImageX(简称ImageX)为业务提供了灵活、高效的一站式图片处理解决方案,包括了服务端 SDK、上传 SDK 和客户端图片加载 SDK。本文就来介绍下 iOS 客户端图…

力扣 1493(删掉一个元素以后全为 1 的最长子数组)Java

目录 题目 约束 用例 解题思路 各位看官先看执行结果 这道题呢,采用的滑动窗口思想。 题目 给你一个二进制数组 nums ,你需要从中删掉一个元素。 请你在删掉元素的结果数组中,返回最长的且只包含 1 的非空子数组的长度。 如果不存在…

15天学习MySQL计划-索引(进阶篇)第七天

索引 1.索引概述 1.介绍 索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数…

HTTP1.1(十二)Cookie的格式与约束

一 Cookie的格式与约束 ① Cookies是什么 1) cookie是我们在前端编程中经常使用的概念2) 使用cookie利用浏览器帮助我们保存客户的相关状态信息,保存用户已经做了什么事情3) 重点和难点[1]、cookie的工作原理[2]、cookie的限制是什么[3]、session又是怎样与cookie关联起来 …

【Android Framework (七) 】- ActivityManagerService(AMS)

文章目录 知识回顾启动第一个流程initZygote的流程system_serverServiceManagerBinderLauncher的启动 前言源码分析1.AMS的启动. ActivityManagerService.java2.setSystemProcess3.应用进程的初始化4.Activity的启动流程 拓展知识1.介绍一下Activity的启动流程。2.ActivityMana…

Handbook of MusicPsychology 音乐心理学手册 ( 多纳德·霍杰斯 Donald.A.Hodges) 笔记

由两个以上的音组成的结合音,除了该声波的波形,人耳会另外脑补出不存在的波形 频率相距较远的一些音与频率相距较近的一些音,前者累加的响度比后者要大 除了泛音部分,音的起声部分也是音色辨别的关键 音高、响度、音色、时值&a…

托福高频真词List07 // 附托福TPO阅读真题

目录 ​ 4月24日单词 生词 熟词 4月25日真题 4月24日单词 生词 🍡live in strictly aquatic habitat / əˈkwɑːtɪk / 🍡only live in aquatic environment 只生活在水生环境中 readilyquickly readilyeasily adv 迅速地 adv 轻易地 wide…

聚观早报|中国将是ChatGPT主要对手;​iPhone 15将使用USB-C接口

今日要闻:中国将是ChatGPT主要对手;iPhone 15将使用USB-C接口;31名ChatGPT训练派遣工遭解雇;大疆Mavic 3 Pro无人机高清图曝光;中国红牛回应被禁止生产销售 中国将是ChatGPT主要对手 微软总裁布拉德史密斯接受采访时表…

前端开发之vue动态路由实现方案

前端开发之vue动态路由实现方案 前言2. 实现1、登录页面创建登录函数和watch监听路由2、调用的login方法(1)登录方法(2)存储token 3、router.push的时候调用路由守卫(1)创建路由守卫,建议路由守…

MySQL Community Server 8.0.33安装教程【笔记】

仅安装MySQL Community Server 下载网址:https://dev.mysql.com/downloads/installer/ 1、下载对应版本; 2、下载后,双击安装,弹出界面选择【Custom】; 3、弹出界面选择【MySQL Server 8.0.33 - X64】; 3、弹出界面…

【C++ Metaprogramming】0. 在C++中实现类似C#的泛型类

两年前,笔者因为项目原因刚开始接触C,当时就在想,如果C有类似C#中的泛型限定就好了,能让代码简单许多。我也一度认为: 虽然C有模板类,但是却没办法实现C#中泛型特有的 where 关键词: public c…

Android 13 wificond讲解

wificond介绍 看如下图,可以知道wificond 进程,该进程位于 system/connectivity/wificond 中。wificond 进程通过标准的 nl80211 命令与 Wi-Fi 驱动程序进行通信。 查看手机也能看到wificond 进程 wificond启动 1. 开机的时候通过调用wificond.rc文件启动wificond system…

docker 部署LNMP

准备工作。 #首先获取nginx配置文件 [rootlocalhost ~]# docker pull nginx:1.23.3 [rootlocalhost ~]# docker run --name nginx --restartalways -d -p 80:80 nginx:1.23.3 [rootlocalhost ~]# mkdir -p /usr/local/nginx/{conf,log,html,conf.d} #复制配置文件 [rootlocalh…

易观千帆 | 2023年3月证券APP月活跃用户规模盘点

易观:2023年3月证券服务应用活跃人数14131.58万人,相较上月,环比增长0.61%,同比增长0.60%;2023年3月自营类证券服务应用Top10 活跃人数6221.44万人,环比增长0.08%;2023年3月第三方证券服务应用T…

使用Spring的五大类注解读取和存储Bean

目录 1.存储Bean对象的注解 1.1 五大类注解 1.2 方法注解 1.3添加注解的依赖 2.注解的使用 2.1 controller注解 2. 2Service注解 2.3.Resopsitory注解 2.4Component注解 2.5Configuration注解 2.6 注解之间的关系 3.方法注解 3.1 方法注解要配合类注解来使用。 3.2…

【Python】ddddoc进行OCR识别和目标检测 ——识别验证码和滑块(安装部署+测试代码注释详细)

目录 安装部署gitee已经上传完整项目requiremen.txt插件作者更新地址 项目结构第一部分 OCR识别部分第二部分 目标检测部分总结 欢迎关注 『Python』 系列,持续更新中 欢迎关注 『Python』 系列,持续更新中 安装部署 gitee已经上传完整项目 requiremen.…

图片对象列表查询与展示(vue+springboot+elementUI)

本文描述场景为 展示:后端从数据库中查询图片对象列表,返回前端展示 多图片展示 先看一下后端表实体 import com.zpmc.common.domain.BaseEntity; import io.swagger.annotations.ApiModel; import lombok.*;import javax.persistence.*; import java.…

8086汇编之乘法指令MUL

2023年4月22日,周六晚上。 今天写汇编作业的时候,碰到了MUL指令,于是把学习到的MUL指令知识记录下来,也可以通过写这篇博客彻底理清MUL指令。 当被乘数和乘数都是8位时: 怎么判断被乘数和乘数是不是8位的&#xff1f…

操作系统之认识进程

目录 什么是进程 进程的状态和转换 进程控制 进程通信 什么是进程 在电脑的任务管理器中,能看到电脑当前运行着的所有进程 那到底什么是进程呢?和我们所看所写的那些程序有什么区别? 操作系统是如何区分这些进程的呢? 那就需要…