Redis事务详解

本文详细介绍了Redis事务的使用流程、原子性特性、watch命令的应用以及6.0.9版本后新的事务抛弃规则。重点讲解了如何在没有乘法操作的情况下处理复杂计算,并提到了watch命令确保数据一致性的重要性。
摘要由CSDN通过智能技术生成
Redis事务篇

Redis事务相比mysql数据库比较简单,事务共有三个主要的命令,multi(用于开启事务),exec(用于执行事务),discard(用于抛弃事务);

Redis事务执行的流程:

1。执行multi命令开启一个事务;

2.申明一系列指令,这时Redis-server收到指令后不会立即执行事务中的命令,而是放入一个事务指令的队列中等待客户端发送exec指令;

3.执行exec指令,当Redis-server接收到exec指令后就会开始执行事务队列中的指令,由于Redis是单线程

所以可以保证事务执行的隔离性和相对的原子性;(或者执行discard命令使得Redis-server抛弃事务队列中的命令)

> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1

Redis事务的原子性并不是真正的原子性:

当在事务中的命令有语法上的错误时,整个事务会被discard;

但是到了执行exec命令之前并没有报错,执行exec命令后Redis-server开始执行事务中的命令,这时如果事务中的命令有误,整个事务并不会回滚,只有错误的命令不会执行,而正确的命令会被执行;(有一个小细节,当执行事务中redis-server突然挂了,这时事务可能刚执行到一半,但是aof已经记录了该事务的部分命令,可能会导致redis-server重启的时候报错,可以使用Redis-check-aof工具修复;Redis不支持回滚是因为Redis想保存Redis的高性能和简单;假设一下如果要支持事务需要做些什么,在mysql里是将修改的命令记录在undo.log中,当需要回滚时就执行undo.log中的回滚操作;

由于Redis的事务和一般的数据库的事务有区别:事务的命令会放入在Redis-server的事务队列中,直到执行exec命令时才会执行所有的事务命令,所以有这样的场景:在Redis有一个number的整数值,现在需要将它乘n再加上m,但是Redis并没有直接提供乘法的命令,所以我们一般需要将number读到客户端,然后进行算术运算,在通过set 命令更新值;但是由于在一个事务过程中我们是没法得到number的值(因为命令直到exec才开始执行命令),这就需要在事务执行前就需要通过get命令得到值,然后在set;但是这样显然是违背了数据并发执行过程中的数据安全;所以Redis提供了一个watch命令,这个命令具有CAS(check and set)功能;我们先展示一下使用方式吧:

mset n1 1 n2 2

watch n1 n2

init n1=get(n1);

int n2=get(n2);

multi

set(n1+n2)

set(n1+n2)

exec

我们一般会在一个事务开启之前用watch命令盯住一个或者多个变量,如果在这个事务执行exec命令之前有任何客户端更改了watched中的任何一个变量Redis-server都会抛弃这个事务;注意如果即使是执行watch命令的客户端如果在watch命令和multi命令之间对watched变量进行修改都会报错;
在这里插入图片描述

最后返回null就是抛弃事务的意思;在Redis版本为 6.0.9之前,Redis-server自身的修改(过期)不会造成事务被抛弃,在6.0.9之后就有了这个功能,如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值