快速了解 Redis 事务

1.相关指令

Redis 事务本质上是在服务器上搞了⼀个"事务队列"。每次客⼾端在事务中进⾏⼀个操作,都会把命令先发给服务器,放到"事务队列"中(但是并不会⽴即执⾏)⽽是会在真正收到EXEC命令之后,才真正执⾏队列中的所有操作。

  1. multi
  • 开启事务
java 复制代码
multi
  1. exec
  • 执行事务
java 复制代码
exec
  1. discard
java 复制代码
discard

2.Redis 事务的特性

Redis 的事务与 MySQL 事务有很大的区别。

  1. 不保证原子性:Redis 没有"回滚机制",只能做到这些操作"批量执行"。不能做到"⼀个失败就恢复到初始状态"。
  • Redis 初始时没有数据
  1. 不需要隔离性:事务中的所有命令都会按顺序执行(注意是执行,要 exec 后),不会被其他客户端的命令打断(Redis 是单线程执行请求的)。

  2. 不需要持久性:Redis 是保存在内存的。是否开启持久化要看配置,和事务⽆关。

  3. 不保证⼀致性:MySQL 的⼀致性体现的是运⾏事务前运⾏后,结果都是合理有效的,不会出现中间⾮法状态。而 Redis 事务,有可能出现数据不一致的情况。

  • 客户端1:
java 复制代码
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key1 200
QUEUED
  • 客户端2:
java 复制代码
127.0.0.1:6379> set key1 100
OK
  • 客户端1:
java 复制代码
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key1 200
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
127.0.0.1:6379> 
  • 客户端2:
java 复制代码
127.0.0.1:6379> set key1 100
OK
127.0.0.1:6379> get key1
"200"
127.0.0.1:6379> 

可以看到,在没有提交事务前,如果有其它客户端修改事务中相关的数据,可能让造成其它客户端的更新丢失了。比如上面案例的客户端2,如何解决呢?可以通过搭配 watch 指令来完成。

3.watch 指令

  1. 当开启事务的时候,如果对 watch 的 key 进⾏修改,就会记录当前 key 的"版本号"。(版本号是个简单的整数,每次修改都会使版本变⼤)
  2. 在真正提交事务的时候,如果发现当前服务器上的 key 的版本号已经超过了事务开始时的版本号,就会让对应的 key 执⾏失败,但是没有被 watch 监控的 key 还是会被执行。
  • 客户端1:
java 复制代码
127.0.0.1:6379> watch key
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key 100
QUEUED
127.0.0.1:6379(TX)> set key1 200
QUEUED
127.0.0.1:6379(TX)> 
  • 客户端2:
java 复制代码
127.0.0.1:6379> set key 20
OK
127.0.0.1:6379> 
  • 客户端1:
java 复制代码
127.0.0.1:6379> watch key
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key 100
QUEUED
127.0.0.1:6379(TX)> set key1 200
QUEUED
127.0.0.1:6379(TX)> exec
(nil)
127.0.0.1:6379> get key
"20"
127.0.0.1:6379> get key1
"200"
127.0.0.1:6379> 
  • 客户端2:
java 复制代码
127.0.0.1:6379> set key 20
OK
127.0.0.1:6379> get key
"20"
127.0.0.1:6379>

注意到,并没有停止执行事务。没有被 watch 监控的 key 还是会被执行。

相关推荐
炫酷的伊莉娜2 小时前
【Redis】零碎知识点(易忘 / 易错)总结回顾
redis
一个天蝎座 白勺 程序猿4 小时前
Python爬虫(29)Python爬虫高阶:动态页面处理与云原生部署全链路实践(Selenium、Scrapy、K8s)
redis·爬虫·python·selenium·scrapy·云原生·k8s
程序员爱钓鱼5 小时前
匿名函数与闭包(Anonymous Functions and Closures)-《Go语言实战指南》原创
后端·golang
追风赶月、5 小时前
【Redis】哨兵(Sentinel)机制
数据库·redis·sentinel
vvilkim5 小时前
Redis持久化机制详解:保障数据安全的关键策略
数据库·redis·缓存
大数据魔法师6 小时前
Redis(三) - 使用Java操作Redis详解
java·数据库·redis
IT光6 小时前
Redis 五种类型基础操作(redis-cli + Spring Data Redis)
java·数据库·redis·spring·缓存
言之。6 小时前
Go 语言中接口类型转换为具体类型
开发语言·后端·golang
diving deep7 小时前
XML简要介绍
xml·java·后端
Uranus^7 小时前
深入解析Spring Boot与Redis集成:高效缓存实践
java·spring boot·redis·缓存