【征服redis2】redis的事务介绍

目录

目录

1.redis事务介绍

2 事务出错的处理

3.Java如何使用redis事务


1.redis事务介绍

在前面我们介绍了redis的几种典型数据结构和应用,本文我们来看一下redis的事务问题。事务也是数据库的重要主题,熟悉关系型数据库的读者应该对事务比较了解,简单地说,事务表示一组动作,要么全部执行,要么全部不执行。例如在社交网站上用户 A关注了用户B,那么需要在用户A的关注表中加入用户B,并且在用户B的粉丝表中添加用户A,这两个行为要么全部执行,要么全部不执行,否则会出现数据不一致的情况。

Redis提供了简单的事务功能,将一组需要一起执行的命令放到 multi和exec两个命令之间。multi命令代表事务开始,exec命令代表事务 结束,它们之间的命令是原子顺序执行的,例如下面操作实现了上述用户关注问题。

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> sadd user:a:follow user:b
QUEUED
127.0.0.1:6379(TX)> sadd user:b:fans user:a
QUEUED

可以看到sadd命令此时的返回结果是QUEUED,代表命令并没有真 正执行,而是暂时保存在Redis中。如果此时另一个客户端执行 sismember user:a:follow user:b返回结果应该为0。

127.0.0.1:6379> sismember user:a:follow user:b
(integer) 0

只有当exec执行后,用户A关注用户B的行为才算完成,如下所示返回的两个结果对应sadd命令。

第一个终端:
127.0.0.1:6379(TX)> exec
1) (integer) 1
2) (integer) 1第二个终端:
127.0.0.1:6379> sismember user:a:follow user:b
(integer) 1

如果要停止事务的执行,可以使用discard命令代替exec命令即可。

2 事务出错的处理

如果事务中的命令出现错误,Redis的处理机制也不一样。

情况1.命令错误

例如下面操作错将set写成了sett,属于语法错误,会造成整个事务无法执行,key和counter的值未发生变化。

比如说我们按照下面的方式来执行redis事务:

127.0.0.1:6379> mget key counter

1) "2"

2) "100"

127.0.0.1:6379> 

127.0.0.1:6379> multi

OK

127.0.0.1:6379(TX)> sett key world

(error) ERR unknown command `sett`, with args beginning with: `key`, `world`, 

127.0.0.1:6379(TX)> incr counter

QUEUED

127.0.0.1:6379(TX)> exec

(error) EXECABORT Transaction discarded because of previous errors.

127.0.0.1:6379> mget key counter

1) "2"

2) "100"

127.0.0.1:6379> 

可以看到最后的counter并没有发生变化。

情况2.运行时错误

例如用户B在添加粉丝列表时,误把sadd命令写成了zadd命令,这种就是运行时命令,因为语法是正确的,redis是无法察觉到这种错误的。例如:

127.0.0.1:6379> multi

OK

127.0.0.1:6379(TX)> sadd user:a:follow user:b

QUEUED

127.0.0.1:6379(TX)> zadd user:b:fans 1 user:a

QUEUED

127.0.0.1:6379(TX)> exec

1) (integer) 0

2) (error) WRONGTYPE Operation against a key holding the wrong kind of value

127.0.0.1:6379> sismember user:a:follow user:b

(integer) 1

127.0.0.1:6379> 

可以看到Redis并不支持回滚功能,sadd user:a:follow user:b命令已经执行成功,开发人员需要自己修复这类问题。

有些应用场景需要在事务之前,确保事务中的key没有被其他客户 端修改过,才执行事务,否则不执行(类似乐观锁)。Redis提供了watch命令来解决这类问题,下表展示了添加watch之后两个客户端执行命令的时序。

可以看到“客户端-1”在执行multi之前执行了watch命令,“客户 端-2”在“客户端-1”执行exec之前修改了key值,造成事务没有执行(exec 结果为nil),整个代码如下所示:

客户端1:

127.0.0.1:6379> set key "java"

OK

127.0.0.1:6379> watch key

OK

127.0.0.1:6379> multi

OK

此时客户端2执行:

append key python

然后回到客户端1:

127.0.0.1:6379(TX)> append key jedis

QUEUED

127.0.0.1:6379(TX)> exec

(nil)

127.0.0.1:6379> get key

"javapython"

127.0.0.1:6379>

Redis提供了简单的事务,之所以说它简单,主要是因为它不支持 事务中的回滚特性,同时无法实现命令之间的逻辑关系计算,当然也体现了Redis的“keep it simple”的特性,下一小节介绍的Lua脚本同样可以实现事务的相关功能,但是功能要强大很多。

3.Java如何使用redis事务

我们前面通过redis客户端命令来学习了事务,在程序中,我们一定是让java调用某个api来实现这些功能的。

我们介绍过jedis的用法,使用jedis来实现事务功能的代码也非常简单:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;public class JedisTransactionDemo {public static void main(String[] args) {Jedis jedis = new Jedis("localhost", 6379);Transaction transaction = jedis.multi(); // 开启事务try {transaction.set("name", "哈哈");transaction.set("age", "18");transaction.exec(); // 提交事务} catch (Exception e) {transaction.discard(); // 回滚事务} finally {jedis.close(); // 关闭连接}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openGauss学习笔记-202 openGauss 数据库运维-常见故障定位案例-不同用户查询同表显示数据不同

文章目录 openGauss学习笔记-202 openGauss 数据库运维-常见故障定位案例-不同用户查询同表显示数据不同202.1 不同用户查询同表显示数据不同202.1.1 问题现象202.1.2 原因分析202.1.3 处理办法 openGauss学习笔记-202 openGauss 数据库运维-常见故障定位案例-不同用户查询同表…

FPGA之分布RAM(1)

SLICEM 资源可以实现分布式 RAM。可以实现的 RAM 类型: 单口 RAM 双端口 简单的双端口 四端口 下表给出了通过1SLICEM中的4个LUT可以实现的RAM类型 1.32 X2 Quad Port Distributed RAM 我们介绍过把 6 输入 LUT 当作 2 个 5输入 LUT 使用,在这里&a…

【蓝桥杯EDA设计与开发】资料汇总以及立创EDA及PCB相关技术资料汇总(持续更新)

[18/01/2024]:目前为了准备蓝桥杯做一些资料贴,于是写下这一篇博客。 各种资料均来源于网络以及部分书籍、手册等文档,参考不保证其准确性。 如果在准备蓝桥杯,可与我私信共同学习!!!&#xf…

每日OJ题_算法_滑动窗口⑤_力扣904水果成篮

目录 力扣904. 水果成篮 解析及代码1(使用容器) 解析及代码2(开数组) 力扣904. 水果成篮 904. 水果成篮 - 力扣(LeetCode) 难度 中等 你正在探访一家农场,农场从左到右种植了一排果树。这…

Next.js 开发指​南(GitHub 115k star​)

Next.js 是一个构建于 Node.js 之上的开源 Web 开发框架,它扩展了最新的 React 特性,集成了基于 Rust 的 JavaScript 工具,可以帮助你快速创建全栈 Web 应用 (full-stack Web applications) 。 对于有一定 React 基础…

Kubernetes部署ingress

文章目录 环境部署ingress可以访问 registry.k8s.io 的环境不能访问 registry.k8s.io 的环境手工部署总结 测试ingress参考 环境 RHEL 9.3Docker Community 24.0.7minikube v1.32.0 部署ingress 可以访问 registry.k8s.io 的环境 通过minikube启用 ingress : m…

【前沿技术杂谈:智能对话的未来】深入比较ChatGPT与文心一言

【前沿技术杂谈:智能对话的未来】深入比较ChatGPT与文心一言 引言主体智能回复语言准确性知识库丰富度 深入分析:ChatGPT与文心一言的技术对比技术架构和算法数据处理和隐私用户界面和体验 应用场景分析未来展望技术进步的趋势潜在的挑战对社会的影响 结…

Kotlin 移动端多平台

支持多平台编程是 Kotlin 的主要优势之一。它减少了为不同平台编写和维护相同代码所花费的时间,同时保留了本机编程的灵活性和优势。 1. 基本概念 KMM:Kotlin Multiplatform for mobile(移动设备的 Kotlin 多平台) KMM 多平台的主…

最新ChatGPT/GPT4科研应用与AI绘图及论文高效写作

详情点击链接:最新ChatGPT/GPT4科研应用与AI绘图及论文高效写作 一OpenAI 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析,AI画图,图像识别,文档API 3.GPT Store 4.从0到1创建自己的GPT应用 5. 模型Gemini以及大模型Clau…

大数据开发之Kafka(概述、快速入门、生产者)

第 1 章:Kafka概述 1.1 定义 Kafka是一个分布式的基于发布/订阅模式的消息队列,主要应用于大数据实时处理领域。 发布/订阅:消息的发布者不会将消息直接发送给特定的订阅者,而是将发布的消息分为不同的类别,订阅者只…

机器学习算法理论:贝叶斯

贝叶斯定理对于机器学习来说是经典的概率模型之一,它基于先验信息和数据观测来得到目标变量的后验分布。具体来说,条件概率(也称为后验概率)描述的是事件A在另一个事件B已经发生的条件下的发生概率,公式表示为P(A|B)&a…

Vue-23、Vue收集表单数据

1、效果 2、代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>收集表单数据</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm/vue2/dist/vue.js…