当前位置: 首页 > 知识库问答 >
问题:

Redis中的事务和监视语句

辛建业
2023-03-14
redis.multi() 
current = redis.get('powerlevel') 
redis.set('powerlevel', current + 1) 
redis.exec()
redis.watch('powerlevel') 
current = redis.get('powerlevel') 
redis.multi() 
redis.set('powerlevel', current + 1) 
redis.exec()

如果另一个客户机在我们调用watch之后更改了powerlevel的值,我们的事务将失败。如果没有客户端更改该值,则该集合将工作。我们可以在循环中执行这段代码,直到它起作用为止。

为什么不能在不能被其他命令打断的事务中执行增量?为什么我们需要迭代而不是等到没有人改变值才开始事务?

共有1个答案

章晋鹏
2023-03-14

这里有几个问题。

1)为什么不能在不能被其他命令打断的事务中执行增量?

首先请注意,Redis“事务”与大多数人认为的经典DBMS中的事务完全不同。

# Does not work
redis.multi() 
current = redis.get('powerlevel') 
redis.set('powerlevel', current + 1) 
redis.exec()

如果我们不使用watch/multi/exec,我们将有一个潜在的竞争条件:

# Initial arbitrary value
powerlevel = 10
session A: GET powerlevel -> 10
session B: GET powerlevel -> 10
session A: current = 10 + 1
session B: current = 10 + 1
session A: SET powerlevel 11
session B: SET powerlevel 11
# In the end we have 11 instead of 12 -> wrong

现在让我们添加一个watch/multi/exec块。使用WATCH子句,MULTI和EXEC之间的命令仅在值未更改时执行。

# Initial arbitrary value
powerlevel = 10
session A: WATCH powerlevel
session B: WATCH powerlevel
session A: GET powerlevel -> 10
session B: GET powerlevel -> 10
session A: current = 10 + 1
session B: current = 10 + 1
session A: MULTI
session B: MULTI
session A: SET powerlevel 11 -> QUEUED
session B: SET powerlevel 11 -> QUEUED
session A: EXEC -> success! powerlevel is now 11
session B: EXEC -> failure, because powerlevel has changed and was watched
# In the end, we have 11, and session B knows it has to attempt the transaction again
# Hopefully, it will work fine this time.

因此,您不必迭代直到没有人更改值,而是一次又一次地尝试操作,直到Redis确定值是一致的,并发出成功的信号。

 类似资料:
  • 主要内容:Redis事务特性,Redis事务命令,Redis事务应用Redis 事务的目的是方便用户一次执行多个命令。执行 Redis 事务可分为三个阶段: 开始事务 命令入队 执行事务 Redis事务特性 Redis 事务具有两个重要特性: 1) 单独的隔离操作 事务中的所有命令都会被序列化,它们将按照顺序执行,并且在执行过的程中,不会被其他客户端发送来的命令打断。 2) 不保证原子性 在 Redis 的事务中,如果存在命令执行失败的情况,那么其他命令依然会被执

  • Redis事务允许一组命令在单一步骤中执行。事务有两个属性,说明如下: 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 Redis事务是原子的。原子意味着要么所有的命令都执行,要么都不执行; 一个事务从开始到执行会经历以下三个阶段: 开始事务 命令入队 执行事务 redis 127.0.0.1:6379> MULTI

  • 主要内容:Redis 事务,1. 事务介绍,2. 实例,3. 实例,4. Discard命令,5. Exec命令,6. Multi命令,7. Unwatch命令,8. Watch命令Redis 事务 1. 事务介绍 Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证: 批量操作在发送 EXEC 命令前被放入队列缓存。 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。 一个事务

  • null Redis事务是有限的,无法特定键,并且所有键在上都不被监视;我们仅限于给定客户端上的单个正在进行的事务。 我见过许多redis用户声称lua脚本是他们所需要的全部的线程。甚至redis官方文档也表示,他们可能会删除交易,转而支持lua脚本。然而,有些情况下这是不够的,比如最标准的情况:使用redis作为缓存。 假设我们想从Redis中的持久数据存储中缓存一些数据。下面是一个快速的过程:

  • 本文向大家介绍Spring事务事件监控的实现,包括了Spring事务事件监控的实现的使用技巧和注意事项,需要的朋友参考一下 前面我们讲到了Spring在进行事务逻辑织入的时候,无论是事务开始,提交或者回滚,都会触发相应的事务事件。本文首先会使用实例进行讲解Spring事务事件是如何使用的,然后会讲解这种使用方式的实现原理。 1.示例 对于事务事件,Spring提供了一个注解@Transaction