事务
事务表示一组动作,要么全部执行,要么全不执行。例如在抖音上用户A关注了用户B,在用户A的关注的人中要添加用户B,在用户B的粉丝中要添加用户A,这些操作要么全部执行,要不全不执行,否则就会造成数据不同步的问题,比如用户A关注了用户B,用户A关注的人中有用户B,但是用户B的粉丝中并没有用户A。
命令
Redis实现了一套比较简单的事务功能,一共有五个关于事务的命令。
命令 | 说明 |
---|---|
WATCH | 监视某个或多个键 |
UNWATCH | 取消监视所有被监视的键 |
MULTI | 标记事务的开始 |
EXEC | 执行一个事务中的所有命令 |
DISCARD | 取消事务 |
将一组需要被一起执行的命令放到MULTI和EXEC命令之间即可实现一个事务。
# 事务实现的示例代码
# 客户端1
> multi
"OK"
> set key1 1
"QUEUED"
> set key2 1
"QUEUED"
> exec
1) "OK"
2) "OK"
> mget key1 key2
1) "1"
2) "1"
可以看到在执行set命令时,返回结果为QUEUED,代表此时命令并没有真的去执行,而是暂时保存在了Redis中。如果我们此时在另一个客户端中执行get命令,会发现返回结果为nil。
# 客户端1
> multi
"OK"
# 客户端1
> set key1 1
"QUEUED"
# 客户端1
> set key2 1
"QUEUED"
# 客户端2
> get key1
(nil)
只有当执行EXEC命令后,事务中的命令才会真的执行完成。
如果中途我们想停止此次事务的执行,我们可以使用DISCARD命令来取消事务。
# 客户端1
> discard
"ok"
> get key1
(nil)
报错时事务的处理机制
如果在执行事务时出错,Redis也会根据出错的类型不同有不同的处理机制。
1.命令错误
例如将命令set写成了sett,属于是语法错误,Redis根本无法执行,这种情况下事务不会执行成功。
# 示例代码
> get key1
(nil)
> multi
"OK"
> sett key1 1
"ERR unknown command `sett`, with args beginning with: `key1`, `1`, "
> incr key1
"QUEUED"
> exec
"EXECABORT Transaction discarded because of previous errors."
> get key1
(nil)
2.运行时错误
比如set key1=1,set key2 = hello。在事务中对key1,key2 进行incr操作。
可以发现在执行exec命令之后的返回结果中可以看到incr key2 命令报错,但是事务还是执行了且对key1进行了+1操作。因为incr key2命令是正确的,产生的错误是运行时错误。
# 示例代码
> set key1 1
"OK"
> set key2 hello
"OK"
> mget key1 key2
1) "1"
2) "hello"
> multi
"OK"
> incr key1
"QUEUED"
> incr key2
"QUEUED"
> exec
1) "2"
2) "ReplyError: ERR value is not an integer or out of range"
> mget key1 key2
1) "2"
2) "hello"
总结
由此可见,Redis并不支持事务回滚,需要开发人员在开发过程中注意此种情况的发生。
监听键
有些事务需要确保事务在真正的执行之前,事务中的某些键没有被修改过,如果没有被修改则执行事务,否则不执行(乐观锁)。Redis提供了WATCH命令来实现这种功能。
# 示例代码
# 客户端1
> lrange list 0 -1
(empty list or set)
# 客户端1
> rpush list 1
(integer) 1
# 客户端1
> watch list
"OK"
# 客户端1
> multi
"OK"
# 客户端1
> rpush list 3
"QUEUED"
# 客户端2
> rpush list 2
(integer) 2
# 客户端1
> exec
(nil)
# 客户端1
> lrange list 0 -1
1) "1"
2) "2"
只要该键在被监听之后,事务真正执行(EXEC)之前被修改过,则事务将不执行。
同时也可以使用UNWATCH命令取消键的监听,UNWATCH命令会取消监听当前客户端中所有被监听的键。
标签:事务,set,key2,key1,redis,初级,执行,客户端 From: https://www.cnblogs.com/lixiuxiu/p/18574008