H__D  

Redis 事务介绍

  Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

  • 批量操作在发送 EXEC 命令前被放入队列缓存。
  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

  一个事务从开始到执行会经历以下三个阶段:

  • 开始事务。
  • 命令入队。
  • 执行事务。

实例

  以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:

 1 127.0.0.1:6379> MULTI
 2 OK
 3 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
 4 QUEUED
 5 127.0.0.1:6379> GET book-name
 6 QUEUED
 7 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
 8 QUEUED
 9 127.0.0.1:6379> SMEMBERS tag
10 QUEUED
11 127.0.0.1:6379> EXEC
12 1) OK
13 2) "Mastering C++ in 21 days"
14 3) (integer) 3
15 4) 1) "Mastering Series"
16    2) "Programming"
17    3) "C++"

  a、单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

  事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败(类似于java的1/0的运行时异常)不会导致前面已做指令的回滚,也不会造成后续的指令不做。

  这是官网上的说明 From redis docs on transactions:

It's important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.

  比如:

 1 127.0.0.1:6379> multi
 2 OK
 3 127.0.0.1:6379> set a aaa
 4 QUEUED
 5 127.0.0.1:6379> incr a
 6 QUEUED
 7 127.0.0.1:6379> set b bbb
 8 QUEUED
 9 127.0.0.1:6379> exec
10 1) OK
11 2) (error) ERR value is not an integer or out of range
12 3) OK
13 127.0.0.1:6379> get a 
14 "aaa"
15 127.0.0.1:6379> get b
16 "bbb"

  如果在 incr a 处失败,set a 已成功不会回滚,set b 还会继续执行。

  b、若在事务队列中存在命令性错误(类似于java编译性错误),则执行EXEC命令时,所有命令都不会执行

 1 127.0.0.1:6379> multi
 2 OK
 3 127.0.0.1:6379> set a aaa
 4 QUEUED
 5 127.0.0.1:6379> sett b bbb
 6 (error) ERR unknown command `sett`, with args beginning with: `b`, `bbb`, 
 7 127.0.0.1:6379> set c ccc
 8 QUEUED
 9 127.0.0.1:6379> exec
10 (error) EXECABORT Transaction discarded because of previous errors.
11 127.0.0.1:6379> get a
12 (nil)

Redis 事务命令

  1、Redis Discard 命令用于取消事务,放弃执行事务块内的所有命令。

    语法:DISCARD

1 redis 127.0.0.1:6379> MULTI
2 OK
3 redis 127.0.0.1:6379> PING
4 QUEUED
5 redis 127.0.0.1:6379> SET greeting "hello"
6 QUEUED
7 redis 127.0.0.1:6379> DISCARD
8 OK

  2、Redis Exec 命令用于执行所有事务块内的命令。

    语法:Exec

    用法如上实例

  3、Redis Multi 命令用于标记一个事务块的开始。

    事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。

    语法:Multi

    用法如上实例

  4、Redis Unwatch 命令用于取消 WATCH 命令对所有 key 的监视。

    语法:UNWATCH 

1 127.0.0.1:6379> WATCH lock lock_times
2 OK
3 127.0.0.1:6379> UNWATCH
4 OK

  5、Redis Watch 命令用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断

    语法:WATCH key [key ...]

1 127.0.0.1:6379> WATCH lock lock_times
2 OK

 

posted on 2019-09-05 18:59  H__D  阅读(251)  评论(0编辑  收藏  举报