深入浅出Redis(五):Redis的事务机制与ACID原则

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 深入浅出Redis(五):Redis的事务机制与ACID原则

引言

Redis是基于键值对的非关系型数据库,秉承设计简单的原则内部也提供事务机制,但是提供的事务可能不满足ACID原则

本文将深入浅出的介绍如何使用事务、事务命令运行的流程以及Redis事务是否满足ACID原则

事务

Redis提供了multi、exec、discord、watch、unwatch命令来实现事务机制

multi、exec、discord命令

multi命令用来开启事务,exec和discord分别用来执行事务和丢弃事务

 #开启事务
 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> discard
 OK
 127.0.0.1:6379> get k2
 (nil)

使用multi命令开启事务后,会将所有的命令放入事务队列中

使用exec命令开始执行时,会依次执行事务队列中的命令

 #开启事务
 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> mget k2 k3
 QUEUED
 #执行事务
 127.0.0.1:6379> exec
 1) OK
 2) OK
 3) OK
 4) 1) "v2"
    2) "v3"

watch、unwatch命令

watch命令用于multi开启事务之前,用来监听某个键对象,执行事务时判断这个键对象是否改变,如果改变则事务不会执行

使用unwatch命令来对监视的键值对进行解锁

 127.0.0.1:6379> set money 100
 OK
 127.0.0.1:6379> set out 0
 OK
 127.0.0.1:6379> watch money # 监视 money
 OK
 127.0.0.1:6379> multi
 OK
 127.0.0.1:6379> decrby money 50
 QUEUED
 127.0.0.1:6379> incrby out 50
 QUEUED
 127.0.0.1:6379> exec  #执行之前,另外一个线程修改了money为666
 (nil)
 127.0.0.1:6379> unwatch
 OK
 127.0.0.1:6379> watch money
 OK
 127.0.0.1:6379> multi
 OK
 127.0.0.1:6379> decrby money 10
 QUEUED
 127.0.0.1:6379> incrby out 10
 QUEUED
 127.0.0.1:6379> exec
 1) (integer) 656
 2) (integer) 10

watch功能由watch字典实现,watch字典Key为监视的key,Value为监视Key的所有客户端

当发生写命令后检查watch字典是否存在操作的KEY,存在则拿到对应Value中客户端,对客户端进行标志,当客户端执行事务exec前判断客户端是否标志,标志说明其他事务修改过拒绝执行

watch监控的key发生变动后,保证事务不会执行成功,并返回null,可以用来做乐观锁(上游业务收到为null就重试【先unwatch再watch】)

ACID原则

事务ACID原则分别代表着原子性、一致性、隔离性、持久性

原子性

原子性是一组事务要么都成功,要么都失败

当命令输入错误会在执行时直接报错,这种情况下能够满足原子性

 127.0.0.1:6379> multi
 OK
 127.0.0.1:6379> set k1 k1
 QUEUED
 127.0.0.1:6379> seg k2 k2 #人为错误命令
 (error) ERR unknown command `seg`, with args beginning with: `k2`, `k2`, 
 127.0.0.1:6379> exec
 (error) EXECABORT Transaction discarded because of previous errors.

当命令出现语法错误时,不在执行时直接报错,会执行到具体命令时才报错,这种情况下除了不报错的命令不执行,事务中其他正常的命令会执行,不能满足原子性

 127.0.0.1:6379> keys *
 (empty array)
 127.0.0.1:6379> multi
 OK
 127.0.0.1:6379> set k1 k1
 QUEUED
 127.0.0.1:6379> incr k1 #人为语法错误
 QUEUED
 127.0.0.1:6379> exec
 1) OK
 2) (error) ERR value is not an integer or out of range
 127.0.0.1:6379> keys *
 1) "k1"

Redis认为以上两种错误是开发、测试阶段才出现的,生产环境不会出现,秉承简单设计原则,没有提供回滚功能

当Redis执行事务到一半时,发生宕机也不能满足原子性

只有当命令不出现语法错误、服务不宕机的情况下才能够满足原子性

隔离性

隔离性问题的产生在于数据库系统多线程执行,但Redis是单线程执行命令的,并且执行事务时是对事务队列中的命令依次执行,因此Redis不会出现隔离性问题

一致性

一致性通常由业务层来校验保证,在不宕机的情况下是满足一致性的

持久性

持久性是事务执行成功时就持久化到磁盘

默认使用RDB进行持久化,这种方式是不能满足持久性的

当持久化策略为AOF always每次刷盘时,事务执行成功时能够保证每条命令持久化

不了解Redis持久化的同学,可以看上一篇文章深入浅出Redis(四):Redis基于RDB、AOF的持久化

总结

本篇文章围绕Redis提供的事务机制,深入浅出的介绍了事务相关命令的使用与原理以及事务ACID原则

事务开始时会将事务中的命令放入事务队列,事务执行时是对事务队列中的命令依次执行

watch命令用watch字典实现,Key为监控的key,Value为监视Key的所有客户端;当对监控的key写操作时,会监控key的所有客户端做标记,客户端执行事务时服务端判断客户端是否有标记,有则说明监视期间被修改,不允许执行事务

命令错误会在事务执行时就报错,导致事务不能执行;命令的语法错误则是会在事务执行中单独报错,未提供回滚机制

当持久化策略改为aof每次刷盘时,则能够满足持久性

最后

  • 参考资料
  • 《Redis深度理解》
  • 《Redis设计与实现》


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4天前
|
NoSQL Redis 数据库
10- 你们用过Redis的事务吗 ? 事务的命令有哪些 ?
```markdown Redis事务包括MULTI、EXEC、DISCARD、WATCH四个命令。虽具备事务功能,但在实际开发中使用较少。 ```
44 7
|
4天前
|
存储 NoSQL Redis
保障数据安全,提升性能:探秘Redis AOF持久化机制在在线购物网站的应用
保障数据安全,提升性能:探秘Redis AOF持久化机制在在线购物网站的应用
|
5天前
|
NoSQL Redis
Redis事务:保证数据操作的一致性和可靠性
Redis事务:保证数据操作的一致性和可靠性
|
3天前
|
NoSQL 算法 Java
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
|
4天前
|
存储 NoSQL 关系型数据库
【Redis】Redis的特性和应用场景 · 数据类型 · 持久化 · 数据淘汰 · 事务 · 多机部署
【Redis】Redis的特性和应用场景 · 数据类型 · 持久化 · 数据淘汰 · 事务 · 多机部署
15 0
|
5天前
|
NoSQL Redis 数据库
Redis实现数据持久性主要依赖两种机制
【5月更文挑战第15天】Redis持久化包括RDB快照和AOF日志。RDB通过定时内存数据快照生成文件,恢复速度快但可能丢失部分数据;AOF记录每次写操作,实时性好但文件大、恢复慢。混合持久化兼顾两者优点,提供数据安全与性能平衡。用户可按需选择或组合使用策略。
7 2
|
4天前
|
监控 NoSQL 关系型数据库
Redis 事务 与 管道
Redis 事务 与 管道
12 0
|
4天前
|
缓存 NoSQL Java
【Redis系列笔记】Redis事务
Redis事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
68 3
|
4天前
|
监控 NoSQL Java
|
4天前
|
负载均衡 监控 NoSQL
Redis的几种主要集群方案
【5月更文挑战第15天】Redis集群方案包括主从复制(基础,读写分离,手动故障恢复)、哨兵模式(自动高可用,自动故障转移)和Redis Cluster(官方分布式解决方案,自动分片、容错和扩展)。此外,还有Codis、Redisson和Twemproxy等工具用于代理分片和负载均衡。选择方案需考虑应用场景、数据量和并发需求,权衡可用性、性能和扩展性。
37 2