redis 事务

本文介绍了Redis事务的基本概念,包括其非原子性和如何通过WATCH指令保证数据一致性,并提供了详细的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、redis事务介绍

Redis中的事务(transaction)是一组命令的集合。事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行。Redis事务的实现需要用到 MULTI EXEC 两个命令,事务开始的时候先向Redis服务器发送 MULTI 命令,然后依次发送需要在本次事务中处理的命令,最后再发送 EXEC 命令表示事务命令结束。

二、Demo

1.正常执行的情况

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> set k3 v3
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) OK
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"

2.取消执行的情况

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> set k5 v5
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"

我们可以看到,当执行DISCARD指令时,k4和k5没有存入内存

3.redis事务与mysql事务的不同点

3.1 非原子性表现

mysql事务内的sql是一组原子操作,要么事务内的多条sql都执行成功,要么事务内的多条sql都执行失败;但是redis事务不是原子性的,如下:虽然k2的值是v2,incr k2这个命令会失败,但是,set k4 v4 和 get k3 这两个命令还是成功了

127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "k3"
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> INCR k2
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) "v3"
3) (error) ERR value is not an integer or out of range
127.0.0.1:6379> get k4
"v4"
127.0.0.1:6379> 

3.2 原子性表现,当指令入队列失败时,redis的事务表现为原子性,如下,set k5 v5 指令没有成功

127.0.0.1:6379> keys *
1) "k4"
2) "k2"
3) "k1"
4) "k3"
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k5 v5
QUEUED
127.0.0.1:6379> set k6
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k5
(nil)
127.0.0.1:6379> 

4.由于redis事务非原子性,所以当一组命令一定要原子性操作时,我们可以使用WATCH key指令,来监控一组事务中,要操作的key,从而保证数据的完整性,如下,假设,一张银行信用卡,我们设置,可刷余额为 100元,我们的欠额为0元,当我们刷卡操作时,监控balance

4.1正常执行情况:

127.0.0.1:6379> set balance 100
OK
127.0.0.1:6379> set debt 0
OK
127.0.0.1:6379> WATCH balance
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY balance 20
QUEUED
127.0.0.1:6379> INCRBY debt 20
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 80
2) (integer) 20
127.0.0.1:6379> get balance
"80"
127.0.0.1:6379> get debt
"20"
127.0.0.1:6379> 

4.2 当redis事务还没有提交时,我们监控的key被改动时,事务会提交失败

127.0.0.1:6379> get balance
"80"
127.0.0.1:6379> get debt
"20"127.0.0.1:6379> WATCH balance
OK
127.0.0.1:6379> set balance 500  #假设,监控了balance,事务还没开启或开启了,没有提交的情况下,balance被更改,事务将会提交失败
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY balance 20
QUEUED
127.0.0.1:6379> INCRBY debt 20
QUEUED
127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> get balance
"500"
127.0.0.1:6379> get debt
"20"
127.0.0.1:6379> 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值