Redis的事务与订阅
# 前言
在数据库中,事务应该具有4个属性:原子性、一致性、隔离性、持久性。
典型的场景就是银行支付的问题,事务的一致性就是保证数据要么全部成功,或者全部失败这样的。
Redis的事务可不是这样的,
Redis的事务更像是一个批处理脚本。所有的命令被封装起来统一执行。中间如果有脚本失败,并不会进行回滚。
# 如何执行?
Redis的事务是怎么执行的呢?一个事务从开始到执行会经历以下三个阶段:
在这个过程中批量操作在发送 EXEC 命令前被放入队列缓存,收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
# 代码示例
如下,我们开启一个事务,内部执行了相关操作,这个时候如果在其他client执行命令都是可以正常执行的。 但是,当执行完exec之后,会覆盖掉其他客户端的定义的key。
还有一点需要注意的是如果sadd失败了,程序还是会正常执行的,不会失败的。这是跟数据库事务的一个很大的区别。
127.0.0.1:6379> MULTI # 开启事务
OK
127.0.0.1:6379> SET name zhangsan
QUEUED
127.0.0.1:6379> GET name
QUEUED
127.0.0.1:6379> SADD tag 'c++' 'php' 'ios'
QUEUED
127.0.0.1:6379> SMEMBERS tag
QUEUED
127.0.0.1:6379> EXEC # 执行事务
1) OK
2) "zhangsan"
3) (integer) 3
4) 1) "ios"
2) "php"
3) "c++"
# DISCARD取消事务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 乐观锁
当使用watch关注之后,事务中无法对该key进行操作
127.0.0.1:6379> GET name
"mogui"
127.0.0.1:6379> WATCH name # 关注x个key,UNWATCH 取消 WATCH 命令对所有 key 的监视。
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET name devil
QUEUED
127.0.0.1:6379> EXEC
(nil)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 订阅频道
订阅频道devil
127.0.0.1:6379> SUBSCRIBE devil
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "devil"
3) (integer) 1
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
发布消息到devil上
127.0.0.1:6379> PUBLISH devil hello
(integer) 1
1
2
2
这个时候订阅方就会收到消息
1) "message"
2) "devil"
3) "hello"
1) "message"
2) "devil"
3) "hello"
1) "message"
2) "devil"
3) "hello"
1) "message"
2) "devil"
3) "hello"
1) "message"
2) "devil"
3) "hello
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
上次更新: 2020/12/31, 06:55:18