Redis事务管理

一、什么是事务

事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。

二、Redis 事务常用命令

这里写图片描述

三、Case 案例

为了说明情况在相对应的命令后面加了解释。

3.1 正确执行
127.0.0.1:6379> MULTI    // 开启事务
OK
127.0.0.1:6379> set k1 v1
QUEUED    // QUEUED 表示入队
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> EXEC    // 执行事务
1) OK
2) "v1"
3) OK
3.2 取消事务
127.0.0.1:6379> FLUSHDB    // 清空数据
OK
127.0.0.1:6379> MULTI    // 开启事务
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> DISCARD    // 取消事务
OK
127.0.0.1:6379> get k1
(nil)
3.3 语法出错,事务回滚
127.0.0.1:6379> FLUSHDB    // 清空数据
OK
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    // 模拟出错
(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 k1
(nil)
127.0.0.1:6379> keys *
(empty list or set)

注:如果执行的命令本身语法出错 (在事务中出错),那么这个事务中的所有命令都不会执行。

3.4 非语法错误,事务不回滚
127.0.0.1:6379> FLUSHDB    // 清空数据
OK
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> INCR k1    // 使 k1 自增 1
QUEUED
127.0.0.1:6379> EXEC    // 执行事务
1) OK
2) OK    // 前两条命令正确执行
3) (error) ERR value is not an integer or out of range    // 由于 v1 是 String 类型不能自增,第三条命令报错
127.0.0.1:6379> mget k1 k2
1) "v1"
2) "v2"

注:如果在事务执行时出错 (在事务中不出错),那么只有出错的命令不执行,其他正确的命令会被执行。

Redis 与传统的关系型数据库事务最大的区别在于,Redis 不支持事务回滚机制。

Redis 的作者在事务功能文档中解释道:不支持复杂的事务回滚机制是因为与 Redis 追求的简单高效主旨不符,并且他认为事务执行出错往往都是编程错误导致的,所以他认为没有必要为 Redis 设计事务回滚功能。

3.5 WATCH 监控 key

正确执行:

127.0.0.1:6379> FLUSHDB    // 清空数据
OK
127.0.0.1:6379> set money 100    // 初始化 money 为 100
OK
127.0.0.1:6379> WATCH money    // 监视 money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 10    // 将 money 减少 10
QUEUED
127.0.0.1:6379> EXEC    // 执行事务,money 变为 90
1) (integer) 90
127.0.0.1:6379> get money
"90"

出错:

127.0.0.1:6379> WATCH money    // 监视 money ,此时 money 为 90
OK
127.0.0.1:6379> DECRBY money 10    // 在事务开始之前将 money 减少 10,money 为 80
(integer) 80
127.0.0.1:6379> get money
"80"
127.0.0.1:6379> MULTI    // 开启事务
OK
127.0.0.1:6379> DECRBY money 10    // 在事务中将 money 减少 10
QUEUED
127.0.0.1:6379> EXEC    // 执行事务,没有命令被执行
(nil)
127.0.0.1:6379> get money    // 查看 money 仍然为 80
"80"

注:在对一个 (或几个) key 进行监视之后,如果这个 (或者几个) key 的值在事务开启之前发生变化,那么在事务中操作这个 (几个)key 的命令将会被打断,有点类似乐观锁的作用。

3.6 UNWATCH 取消监视所有 key
127.0.0.1:6379> WATCH money    // 监视 money 当前 money 为 80
OK
127.0.0.1:6379> UNWATCH    // 取消对所有 key 的监视
OK
127.0.0.1:6379> DECRBY money 10    // 在事务执行之前将 money 减少 10 ,当前执行完 money 为 70
(integer) 70
127.0.0.1:6379> get money 
"70"
127.0.0.1:6379> MULTI    // 开启事务
OK
127.0.0.1:6379> DECRBY money 10    // 将 money 减少 10
QUEUED
127.0.0.1:6379> EXEC    // 执行事务,命令被正确执行
1) (integer) 60
127.0.0.1:6379> get money     // money 被改为了 60
"60"

注:在对 key 进行监视之后,如果想要在事务开启之前操作被监视的 key ,那么可以通过 UNWATCH 取消对所有 key 的监控。

四、总结

4.1 事务的三个状态
  • 开始:以 MULTI 开始一个事务
  • 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
  • 执行:由 EXEC 命令触发事务
4.2 事务特性
  • 原子性:Redis 具备原子性,但是命令执行出错后不支持事务回滚
  • 一致性:Redis 具备一致性
  • 隔离性:Redis 采用单线程执行,因此事务总是以串行的方式执行,因此 Redis 也是具备隔离性的
  • 持久性:Redis 的持久性意味着执行事务产生的结果被永久性的保存到硬盘里,即使服务器宕机,数据也不应该丢失,因此 Redis 的持久性由 Redis 的持久化方案决定。当服务器在 AOF 持久化模型下,当 appendfync 配置为 always 时,Redis 的事务也具备持久性
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值