Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redis:WATCH 命令碰到 MULTI 命令时的不同效果 #1714

Open
MarlonDML opened this issue Apr 30, 2022 · 2 comments
Open

Redis:WATCH 命令碰到 MULTI 命令时的不同效果 #1714

MarlonDML opened this issue Apr 30, 2022 · 2 comments
Labels
enhancement New feature or request or suggestion

Comments

@MarlonDML
Copy link
Contributor

MarlonDML commented Apr 30, 2022

Redis-事务中提到 “WATCH 命令用于监听指定的键,当调用 EXEC 命令执行事务时,如果一个被 WATCH 命令监视的键被修改的话,整个事务都不会执行,直接返回失败”。这个说法似乎不太准确,这里以下面 3 个demo进行说明。

  1. 同一个session中,watch监视的key在multi之前被修改
    image
    根据测试结果可以得知,如果在 MULTI 之前被修改,那么这个事务不会被执行
  2. 同一个session中,watch监视的key在事务内部被修改
    image
    根据测试结果可以得知,如果在 MULTI 之后被修改或者说在事务内部被修改,那么这个事务还是会执行成功
  3. 同一个session中,watch监视的key在事务内部被修改,但是在事务提交之前被其他 session 修改
    image

可以看出,场景一和场景三其实可以当成同一种情况;另外,WATCH 操作只是 session 级别的,不会影响其他 session,在同一个 session 中,对于同一个 Key ,在事务执行之前最多只能加一个 WATCHWATCH 监视的 Key 在事务内部被修改后,无论这个事务是否执行成功,这个 Key 上的 WATCH 就会自动取消(有兴趣的同学可以自行验证)可以得出结论:

只有当 WATCH事务 在同一个 session 里,并且被 WATCH 监视的Key,第一次被修改的操作在事务内部,这个事务才会执行成功

@Snailclimb
Copy link
Owner

WATCH 操作只是 session 级别的,不会影响其他 session,在同一个 session 中,对于同一个 Key ,在事务执行之前最多只能加一个 WATCHWATCH 监视的 Key 在事务内部被修改后,无论这个事务是否执行成功,这个 Key 上的 WATCH 就会自动取消(有兴趣的同学可以自行验证)可以得出结论:

感谢补充,受教了👍

@Snailclimb Snailclimb added the enhancement New feature or request or suggestion label Sep 28, 2022
@Snailclimb
Copy link
Owner

Snailclimb commented Sep 28, 2022

Redis-事务中提到 “WATCH 命令用于监听指定的键,当调用 EXEC 命令执行事务时,如果一个被 WATCH 命令监视的键被修改的话,整个事务都不会执行,直接返回失败”。这个说法似乎不太准确,这里以下面 3 个demo进行说明。

  1. 同一个session中,watch监视的key在multi之前被修改
    image
    根据测试结果可以得知,如果在 MULTI 之前被修改,那么这个事务不会被执行
  2. 同一个session中,watch监视的key在事务内部被修改
    image
    根据测试结果可以得知,如果在 MULTI 之后被修改或者说在事务内部被修改,那么这个事务还是会执行成功
  3. 同一个session中,watch监视的key在事务内部被修改,但是在事务提交之前被其他 session 修改
    image

可以看出,场景一和场景三其实可以当成同一种情况;另外,WATCH 操作只是 session 级别的,不会影响其他 session,在同一个 session 中,对于同一个 Key ,在事务执行之前最多只能加一个 WATCHWATCH 监视的 Key 在事务内部被修改后,无论这个事务是否执行成功,这个 Key 上的 WATCH 就会自动取消(有兴趣的同学可以自行验证)可以得出结论:

只有当 WATCH事务 在同一个 session 里,并且被 WATCH 监视的Key,第一次被修改的操作在事务内部,这个事务才会执行成功

表述完善如下:

你可以通过WATCH 命令监听指定的 Key,当调用 EXEC 命令执行事务时,如果一个被 WATCH 命令监视的 Key 被 其他客户端/Session 修改的话,整个事务都不会被执行。

# 客户端 1
> SET PROJECT "RustGuide"
OK
> WATCH PROJECT
OK
> MULTI
OK
> SET PROJECT "JavaGuide"
QUEUED

# 客户端 2
# 在客户端 1 执行 EXEC 命令提交事务之前修改 PROJECT 的值
> SET PROJECT "GoGuide"

# 客户端 1
# 修改失败,因为 PROJECT 的值被客户端2修改了
> EXEC
(nil)
> GET PROJECT
"GoGuide"

不过,如果 WATCH事务 在同一个 Session 里,并且被 WATCH 监视的 Key 被修改的操作发生在事务内部,这个事务是可以被执行成功的(相关 issue :WATCH 碰到 MULTI 时的不同效果)。

事务内部修改 WATCH 监视的 Key:

> SET PROJECT "JavaGuide"
OK
> WATCH PROJECT
OK
> MULTI
OK
> SET PROJECT "JavaGuide1"
QUEUED
> SET PROJECT "JavaGuide2"
QUEUED
> SET PROJECT "JavaGuide3"
QUEUED
> EXEC
1) OK
2) OK
3) OK
127.0.0.1:6379> GET PROJECT
"JavaGuide3"

事务外部修改 WATCH 监视的 Key:

> SET PROJECT "JavaGuide"
OK
> WATCH PROJECT
OK
> SET PROJECT "JavaGuide2"
OK
> MULTI
OK
> GET USER
QUEUED
> EXEC
(nil)

@Snailclimb Snailclimb changed the title redis——watch碰到multi时的不同效果 Redis:WATCH 命令碰到 MULTI 命令时的不同效果 Sep 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request or suggestion
Projects
None yet
Development

No branches or pull requests

2 participants