redis事务:
在单个操作中可以执行一个或者一组命令。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞。
事务执行的阶段
开始事务、将命令加入队列、执行事务
事务执行
- 正常的事务执行:
127.0.0.1:6380> get v1
"4"
127.0.0.1:6380> MULTI
OK
127.0.0.1:6380> SET v1 2
QUEUED
127.0.0.1:6380> get v1
QUEUED
127.0.0.1:6380> exec
1) OK
2) "2"
- 放弃事务:
127.0.0.1:6380> get v1
"2"
127.0.0.1:6380> MULTI
OK
127.0.0.1:6380> set v1 3
QUEUED
127.0.0.1:6380> get v1
QUEUED
127.0.0.1:6380> DISCARD
OK
127.0.0.1:6380> get v1
"2"
- 事务由于错误命令操作,而退回到开始状态
127.0.0.1:6380> clear
127.0.0.1:6380> get v1
"2"
127.0.0.1:6380> MULTI
OK
127.0.0.1:6380> set v1 1
QUEUED
127.0.0.1:6380> get v1
QUEUED
127.0.0.1:6380> INCRBY v1
(error) ERR wrong number of arguments for 'incrby' command
127.0.0.1:6380> set v1 5
QUEUED
127.0.0.1:6380> get v1
QUEUED
127.0.0.1:6380> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
- 事务由于语法错误,而完成部分原子性操作
127.0.0.1:6380> get v2
"v2"
127.0.0.1:6380> MULTI
OK
127.0.0.1:6380> INCRBY v2 10
QUEUED
127.0.0.1:6380> APPEND v2 _abc
QUEUED
127.0.0.1:6380> get v2
QUEUED
127.0.0.1:6380> EXEC
1) (error) ERR value is not an integer or out of range
2) (integer) 6
3) "v2_abc"
127.0.0.1:6380> get v2
"v2_abc"
Redis事务中不完全保证原子性,支持部分原子性,redis在同一个事务中,如果一条命令由于语法导致执行失败,那么其后的命令仍然会执行,却不会回滚。
Watch监控命令(乐观锁)
- 正常单连接操作:
127.0.0.1:6380> get v1
"2"
127.0.0.1:6380> WATCH v1
OK
127.0.0.1:6380> MULTI
OK
127.0.0.1:6380> SET v1 1
QUEUED
127.0.0.1:6380> GET v1
QUEUED
127.0.0.1:6380> EXEC
1) OK
2) "1"
127.0.0.1:6380> GET v1
"1"
- 多连接操作:
127.0.0.1:6380> get v1
"1"
127.0.0.1:6380> WATCH v1
OK
127.0.0.1:6380> MULTI
OK
-----------------------
新客户端:
127.0.0.1:6380> get v1
"1"
127.0.0.1:6380> set v1 200
OK
127.0.0.1:6380> get v1
"200"
-----------------------
127.0.0.1:6380> INCRBY k1 10
QUEUED
127.0.0.1:6380> EXEC
(nil)
127.0.0.1:6380>
WATCH XXX:监控XXX(watch可以监控一个及多个键)。给XXX上锁。watch这个命令类似于乐观锁,如果监控的key已经被修改了,那么整个监控的事务队列就不会继续执行下去了。也就是watch监控的键,只要有一个发生了改变,那么使用EXEC执行命令就会报出异常,让你基于当前更新后最新的值去操作。
UNWATCH XXX:取消监控。
注意:
① 在执行了exec和unwatch之后,之前加的watch监控锁就会被消除了。
② WATCH需要和MULTI搭配使用,否则监控失效。