Redis事务长什么样?一文带你全面了解

一、概述

1.1、Redis事务简介

在 Redis 中,事务是一组命令的有序队列,Redis 使用 MULTI、EXEC、WATCH 和 DISCARD 等命令来实现事务。事务的执行是原子的,要么所有命令都执行成功,要么所有命令都不执行。事务中的命令在 EXEC 执行之前不会被实际执行,而是先进入队列,从而实现了原子性操作。

1.2、Redis事务方案

  1. Redis事务(Transactions):
  • Redis事务允许你将一系列命令作为一个原子操作来执行。你可以使用MULTI开始事务,然后添加多个命令,最后使用EXEC提交事务。
  • 事务可以包含多个命令,但如果在事务执行期间发生了错误或数据被修改,所有的操作都会被回滚,不会执行任何改变数据的命令。
  1. Redis脚本(Scripting):
  • Redis脚本是使用Lua语言编写的脚本,可以在Redis服务器上原子性地执行。
  • 脚本可以包含多个命令,这些命令将被作为一个整体在服务器上执行,要么全部成功,要么全部失败,保证原子性。
  • 脚本在执行时是单线程的,这意味着它们不会被其他命令或脚本中断,这有助于确保原子性和一致性。
  1. 脚本 vs. 事务:
  • 虽然事务和脚本都可以实现一组命令的原子性执行,但在某些情况下,脚本可能更为简单和高效。
  • 脚本在执行时不需要将多个命令发送到服务器,而是将整个脚本作为一个单一的操作发送,这可以减少通信开销,提高性能。
  • 另外,脚本还可以在执行期间访问参数,使其更加灵活。

对于简单的操作,事务可能足够,但对于更复杂的操作或需要原子性保证的情况,脚本可能是更好的选择。总体而言,Redis脚本提供了更灵活、更高效的方式来执行一系列命令。

二、命令事务实现步骤

使用watch、multi、exec等命令来实现一个简单的转账事务:

step1:设置两个账户的初始余额

bash 复制代码
# 设置两个账户的初始余额
set account1 100
set account2 50

step2:使用watch命令监视两个账户的余额

WATCH命令用于监视一个或多个键,以实现乐观锁(Optimistic Locking)。通过使用WATCH,你可以指定一组键,如果这些键在事务执行期间被其他客户端修改,事务将被取消。这允许你在执行事务之前检查被监视的键是否发生了变化,从而保证事务的原子性。

bash 复制代码
# 使用watch命令监视两个账户的余额
watch account1 account2

step3:开启事务并执行事务

bash 复制代码
# 使用multi命令开启事务
multi
# 在事务中,将account1的余额减少10,将account2的余额增加10
decrby account1 10
incrby account2 10
# 使用exec命令提交事务
exec

step4:事务异常模拟

在multi执行之后exec执行之前,如果再开启一个窗口来操作account1,这时第一个窗口的事务就会执行失败,数据的值不会被改变。

比如在执行multi后,新开一个窗口执行:

窗口2:

arduino 复制代码
set account1 200

然后再回到第一个窗口执行剩下的事务命令,最后就会提示异常:

三、Redis脚本事务

Redis官方提到在Redis中,除了使用传统的事务(通过MULTI、EXEC等命令)外,还可以通过Redis脚本来实现类似事务的操作,而且通常情况下脚本会更简单和更快,这里说的脚本就是我们常使用的Lua脚本。

四、Redis事务特点

Redis的事务有以下特点:

  • Redis的事务是乐观锁的,也就是说,如果事务中涉及的键在执行前被其他客户端修改,那么事务会被中断,不会执行任何命令。这是通过WATCH命令来实现的,它可以监视一个或多个键,如果这些键在事务执行前被修改,那么事务会失败。这样可以保证事务的隔离性和一致性。
  • Redis的事务是基于队列的,也就是说,当客户端执行MULTI命令后,开始一个事务,之后发送的所有命令都会被放入一个队列中,而不是立即执行。只有当客户端执行EXEC命令时,才会触发事务中的所有命令的执行。如果客户端执行DISCARD命令,那么会取消事务,放弃执行队列中的所有命令。

五、Redis事务应用场景

Redis的事务可以用于一些需要保证数据完整性和一致性的场景,例如:

  • 购物车结算:当用户结算购物车时,需要从库存中扣除相应的商品数量,同时更新用户的订单信息。这两个操作需要在一个事务中完成,否则可能会出现库存和订单不一致的情况。可以使用WATCH命令来监视库存的键,如果在事务执行前,库存被其他用户修改,那么事务会失败,提示用户重新结算。
  • 秒杀活动:当用户参与秒杀活动时,需要判断商品是否还有剩余,如果有,就扣除一个商品,并生成一个订单。这两个操作也需要在一个事务中完成,否则可能会出现超卖的情况。同样可以使用WATCH命令来监视商品的键,如果在事务执行前,商品被其他用户抢购,那么事务会失败,提示用户秒杀失败。
  • 排行榜更新:当用户完成某个任务或者获得某个成就时,需要更新用户的积分,并将用户的排名插入到相应的排行榜中。这两个操作也需要在一个事务中完成,否则可能会出现积分和排名不一致的情况。可以使用WATCH命令来监视用户的积分键,如果在事务执行前,用户的积分被其他操作修改,那么事务会失败,提示用户重新更新。
相关推荐
架构师沉默4 分钟前
程序员如何避免猝死?
java·后端·架构
椰奶燕麦22 分钟前
Windows PackageManager (winget) 核心故障排错与通用修复指南
后端
zjjsctcdl1 小时前
springBoot发布https服务及调用
spring boot·后端·https
zdl6861 小时前
Spring Boot文件上传
java·spring boot·后端
世界哪有真情1 小时前
哇!绝了!原来这么简单!我的 Java 项目代码终于被 “拯救” 了!
java·后端
RMB Player1 小时前
Spring Boot 集成飞书推送超详细教程:文本消息、签名校验、封装工具类一篇搞定
java·网络·spring boot·后端·spring·飞书
重庆小透明2 小时前
【搞定面试之mysql】第三篇 mysql的锁
java·后端·mysql·面试·职场和发展
武超杰2 小时前
Spring Boot入门教程
java·spring boot·后端
IT 行者2 小时前
Spring Boot 集成 JavaMail 163邮箱配置详解
java·spring boot·后端
gelald3 小时前
JVM - 运行时内存模型
java·jvm·后端