Redis事务

Redis事务

Redis单条命令式保存原子性的,但是事务不保证原子性!

Redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程的中,会按照顺序执行!

---次性、顺序性、排他性!执行一些列的命令!

Redis事务没有没有隔离级别的概念!

Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务(multi)
  • 命令入队。
  • 执行事务。

正常执行事务

bash 复制代码
127.0.0.1:6379> multi # 开启事务
OK
# 命令入队
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> get k2
QUEUED
127.0.0.1:6379(TX)> exec # 执行事务
1) OK
2) OK
3) OK
4) "v2"

放弃事务

bash 复制代码
127.0.0.1:6379> multi # 开启事务
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED 
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> discard # 取消事务
OK
127.0.0.1:6379> get k4 # 事务队列中命令都不会被执行
(nil)

编译型异常(代码有问题!命令有错),事务中所有的命令都不会被执行!

bash 复制代码
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> getset k3 # 错误的命令
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> set k5 v5
QUEUED
127.0.0.1:6379(TX)> exec # 执行事务报错
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k5 # 所有的命令都不会执行
(nil)

运行时异常(1/0),如果事务队列中存在语法性错误,那么执行命令的时候,其他命令可以正常执行,错误命令抛出异常

bash 复制代码
127.0.0.1:6379> set k1 "v1"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incr k1 # 执行的时候会失败
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> get k3
QUEUED
127.0.0.1:6379(TX)> exec
1) (error) ERR value is not an integer or out of range # 虽然第一条命令报错,但是依旧正常执行成功了
2) OK
3) OK
4) "v3"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> get k3
"v3"

监控

**悲观锁:**正如其名,具有强烈的独占和排他特性。它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,***在整个数据处理过程中,将数据处于锁定状态。***悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

乐观锁:乐观锁是一种并发控制机制,它持有一种乐观的态度,相信数据冲突发生的概率较低,并允许多个任务并行地对数据进行操作,而不加锁**。在乐观锁的机制下,对数据的操作不会立即进行冲突检测和加锁,而是在数据提交时通过一种机制来验证是否存在冲突。

Redis测监视测试

正常执行成功

bash 复制代码
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(TX)> decrby money 20
QUEUED
127.0.0.1:6379(TX)> incrby out 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 80
2) (integer) 20

测试多线程修改值,使用watch可以当做redis的乐观锁操作!

bash 复制代码
127.0.0.1:6379> watch money # 监视money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decrby money 10
QUEUED
127.0.0.1:6379(TX)> incrby out 10
QUEUED
127.0.0.1:6379(TX)> exec # 执行前另外一个线程修改了值,这个时候就会导致事务执行失败
(nil)

如果修改失败,获取最新的值就好

Redis分布式锁实现秒杀业务(乐观锁、悲观锁):[Redis分布式锁实现秒杀业务(乐观锁、悲观锁) - Margaery - 博客园 (cnblogs.com)](

相关推荐
零炻大礼包35 分钟前
【SQL server】数据库远程连接配置
数据库
zmgst44 分钟前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
随心............1 小时前
python操作MySQL以及SQL综合案例
数据库·mysql
€☞扫地僧☜€1 小时前
docker 拉取MySQL8.0镜像以及安装
运维·数据库·docker·容器
CopyDragon1 小时前
设置域名跨越访问
数据库·sqlite
xjjeffery1 小时前
MySQL 基础
数据库·mysql
写bug的小屁孩1 小时前
前后端交互接口(三)
运维·服务器·数据库·windows·用户界面·qt6.3
恒辉信达1 小时前
hhdb数据库介绍(8-4)
服务器·数据库·mysql
ketil272 小时前
Ubuntu 安装 redis
redis
齐 飞2 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb