redis初级——事务

事务

​ 事务表示一组动作,要么全部执行,要么全不执行。例如在抖音上用户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命令会取消监听当前客户端中所有被监听的键。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值