Redis 事务
Redis 中的事务是通过使用 MULTI、EXEC、DISCARD 和 WATCH 命令实现的。以下是这些命令的说明:
-
MULTI:用于标记事务的开始。在执行 MULTI 后,所有后续的命令都将被认为是事务的一部分。
-
EXEC:用于执行之前标记的事务。Redis 将按顺序执行事务中的所有命令。
-
DISCARD:用于取消事务,清空事务队列,并释放与事务关联的任何资源。
-
WATCH:用于监视一个或多个键,以便在事务执行期间检测到键的变化。如果在 EXEC 执行之前被监视的键发生了变化,事务将被取消。
在 Redis 中,事务是一组命令的集合,这些命令将按顺序执行并原子地提交或回滚。Redis 事务使用 MULTI、EXEC、WATCH、DISCARD 等命令实现。
当客户端发送 MULTI 命令时,Redis 将进入事务模式,并将所有后续命令放入一个队列中,直到客户端发送 EXEC 命令。在 MULTI 和 EXEC 之间执行的所有命令都不会立即执行,而仅会进入事务队列中等待执行。只有在执行 EXEC 命令时,Redis 才会遍历事务队列并以原子方式执行其中的所有命令。
因此,在事务的队列期间,Redis 不会阻塞其他客户端请求。但是事务中的命令如果太多的话,那么在执行的时候会因为单线程而让其他的命令处于等待中,造成阻塞。所以事务中的命令尽量少一些。
正常执行
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set aa aa
QUEUED
127.0.0.1:6379> set aaa aaa
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
127.0.0.1:6379> get aa
"aa"
127.0.0.1:6379> get aaa
"aaa"
语法出错
语法出错能回滚
127.0.0.1:6379> set aa aa
OK
127.0.0.1:6379> set aaa aaa
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set aa
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> set aaa bbb
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get aaa
"aaa"
命令出错
aa的值是字符串,不能INCR ,但是能继续执行后续的命令
127.0.0.1:6379> set aa aa
OK
127.0.0.1:6379> set aaa aaa
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> INCR aa
QUEUED
127.0.0.1:6379> set aaa bbb
QUEUED
127.0.0.1:6379> exec
1) (error) ERR value is not an integer or out of range
2) OK
127.0.0.1:6379> get aa
"aa"
127.0.0.1:6379> get aaa
"bbb"
DISCARD命令
127.0.0.1:6379> set aa aa
OK
127.0.0.1:6379> set aaa aaa
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set aa 11
QUEUED
127.0.0.1:6379> set aaa 111
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> get aaa
"aaa"
多事务
客户端1:
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set aa 11
QUEUED
127.0.0.1:6379> set aaa 111
QUEUED
127.0.0.1:6379> exec 步骤1
1) OK
2) OK
127.0.0.1:6379> get aa
"11"
127.0.0.1:6379> get aaa
"111"
127.0.0.1:6379>
客户端2
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set aa 22
QUEUED
127.0.0.1:6379> set aaa 222
QUEUED
127.0.0.1:6379> exec 步骤2
1) OK
2) OK
127.0.0.1:6379> get aa
"22"
127.0.0.1:6379> get aaa
"222"
这里的步骤1先于步骤2执行
watch命令
客户端1
127.0.0.1:6379> get aa
"aa"
127.0.0.1:6379> get aaa
"aaa"
127.0.0.1:6379> watch aa 步骤1
OK
127.0.0.1:6379> MULTI 步骤2
OK
127.0.0.1:6379> set aa 11 步骤3
QUEUED
127.0.0.1:6379> set aaa 111 步骤4
QUEUED
127.0.0.1:6379> exec 步骤6
(nil)
127.0.0.1:6379> get aa
"99"
127.0.0.1:6379> get aaa
"aaa"
客户端2
127.0.0.1:6379> set aa 99 步骤5
OK
127.0.0.1:6379> get aa
"99"
这里的步骤345的顺序可以调换不影响结果,客户端1的执行要回滚
多客户端watch
客户端1
127.0.0.1:6379> WATCH aa
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set aa 11
QUEUED
127.0.0.1:6379> set aaa 111 步骤1
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
客户端2
127.0.0.1:6379> WATCH aa
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set aa 22
QUEUED
127.0.0.1:6379> set aaa 222 步骤2
QUEUED
127.0.0.1:6379> exec
(nil)
客户端3
127.0.0.1:6379> get aa
"11"
127.0.0.1:6379> get aaa
"111"
客户端1先执行到步骤1,然后客户端2执行到步骤2,
再执行客户端1exec,返回结果ok
客户端2exec,返回结果nil
说明客户端2回滚了。
阻塞
在Redis中,DEBUG SLEEP
命令可以用于模拟阻塞的效果。该命令会使当前客户端线程休眠指定的时间。
下面是一个示例,演示如何使用DEBUG SLEEP
命令创建一个阻塞时间较长的事务:
客户端1
MULTI
SET key1 value1
DEBUG SLEEP 10
SET key2 value2
EXEC
这时如果有客户端2查询的话,会阻塞等待客户端1的命令执行结束。
关于回滚
redis的回滚可以理解为取消exec。
在事务中,语法出错导致整个事务无法exec。
但是语法没有问题,命令错误的话是可以 继续执行完整个事务的。
标签:aa,事务,set,aaa,0.1,Redis,6379,127.0 From: https://www.cnblogs.com/fanxingrushui/p/17737155.html