一文讲透 Redis 事务 (事务模式 VS Lua 脚本)

本文详细探讨了 Redis 的事务模式和 Lua 脚本,指出 Lua 脚本在实际场景中更具优势,具备原子性且能保证隔离性。Redis 事务虽然能确保隔离性,但无法保证持久性和回滚,其原子性在特定条件下成立。文章通过实例解释了事务的 ACID 属性,并比较了事务与 Lua 脚本的适用性。
摘要由CSDN通过智能技术生成

准确的讲,Redis 事务包含两种模式 : 事务模式 和 Lua 脚本

先说结论:

Redis 的事务模式具备如下特点:

  • 保证隔离性;

  • 无法保证持久性;

  • 具备了一定的原子性,但不支持回滚;

  • 一致性的概念有分歧,假设在一致性的核心是约束的语意下,Redis 的事务可以保证一致性。

但 Lua 脚本更具备实用场景,它是另一种形式的事务,他具备一定的原子性,但脚本报错的情况下,事务并不会回滚。Lua 脚本可以保证隔离性,而且可以完美的支持后面的步骤依赖前面步骤的结果

Lua 脚本模式的身影几乎无处不在,比如分布式锁、延迟队列、抢红包等场景。

1 事务原理

Redis 的事务包含如下命令:

事务包含三个阶段:

  1. 事务开启,使用 MULTI , 该命令标志着执行该命令的客户端从非事务状态切换至事务状态 ;

  1. 命令入队,MULTI 开启事务之后,客户端的命令并不会被立即执行,而是放入一个事务队列 ;

  1. 执行事务或者丢弃。如果收到 EXEC 的命令,事务队列里的命令将会被执行 ,如果是 DISCARD 则事务被丢弃。

下面展示一个事务的例子。

 redis> MULTI 
 OK
 redis> SET msg "hello world"
 QUEUED
 redis> GET msg
 QUEUED
 redis> EXEC
 1) OK
 1) hello world

这里有一个疑问?在开启事务的时候,Redis key 可以被修改吗?

img

在事务执行 EXEC 命令之前 ,Redis key 依然可以被修改

在事务开启之前,我们可以 watch 命令监听 Redis key 。在事务执行之前,我们修改 key 值 ,事务执行失败,返回 nil 。

img

通过上面的例子,watch 命令可以实现类似乐观锁的效果 。

2 事务的ACID

2.1 原子性

原子性是指:一个事务中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。

第一个例子:

在执行 EXEC 命令前,客户端发送的操作命令错误,比如:语法错误或者使用了不存在的命令。

 redis> MULTI
 OK
 redis> SET msg "other msg"
 QUEUED
 redis> wrongcommand  ### 故意写错误的命令
 (error) ERR unknown command 'wrongcommand' 
 redis> EXEC
 (error) EXECABORT Transaction discarded because of previous errors.
 redis> GET msg
 "hello world"

在这个例子中,我们使用了不存在的命令,导致入队失败,整个事务都将无法执行 。

第二个例子:

事务操作入队时,命令和操作的数据类型不匹配 ,入队列正常,但执行 EXEC 命令异常 。

 redis
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值