6

Redis事务操作

 3 years ago
source link: https://www.wencst.com/archives/1583
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

什么是Redis事务

事务的概念这里就不说了,主要说一下Redis中的事务

可以一次执行多个命令,但本质上是一个命令集。按顺序的执行每一个命令,不会被其他以外的命令影响。

MULTI 标记一个事务的开始 EXEC 执行所有事务块内的命令,执行结束之后释放事务锁 DISCARD取消事务,放弃执行事务块内的所有命令。不保证原子性,一个事务中,有命令执行失败并不会影响事务中的其他命令。没有回滚。

# 开启事务
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> incr num
QUEUED  # 返回QUEUED 表示该命令已经加入队列中
127.0.0.1:6379> incr num
QUEUED
127.0.0.1:6379> decr num
QUEUED
# EXEC 执行事务队列中的所有命令
127.0.0.1:6379> EXEC
1) (integer) 1
2) (integer) 2
3) (integer) 1
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set str abc
QUEUED
127.0.0.1:6379> set str qwer
QUEUED
# 取消事务
127.0.0.1:6379> DISCARD
OK
# set str value并没有生效
127.0.0.1:6379> get str
(nil)

WATCH 监控

WATCH key [key …]

监视一个或者多个Key。如果在执行事务之前这些key被其他命令改动,则事务被打断

UNWATCH

取消watch对key的监视。

WATCH锁类似乐观锁。

乐观锁

假设出现最好的情况,从取数据到修改数据完毕这个时间内,不会有任何人去操作这个数据,因此不会上锁。但是为了确定有没有人真正的去操作这条数据,可以通过版本号(version)的方法实现。

如A同学取一条数据的时候版本号为1,在没有更新完毕的时候,B同学也取了同样的数据,版本号也为1。当A更新完毕之后版本号为2了,B同学再去更新发现版本不一致,就需要重新获取最新的数据。

悲观锁

假设出现最坏的情况,从取数据到更新完毕这个时间内,认为数据会被别人修改。所有拿到数据时会进行加锁操作。这样别人就一直处于阻塞状态,从而无法修改数据。如表级锁,行锁,读写锁等…

如下所示,我们有999块钱,消费了199之后又消费了100(199和100为整体)。此时一切正常,最终剩余700块。

127.0.0.1:6379> set money 999
OK
127.0.0.1:6379> WATCH money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 199
QUEUED
127.0.0.1:6379> DECRBY money 100
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 800
2) (integer) 700
127.0.0.1:6379> get money
"700"

另一种场景,A请求:我得知卡上余额999元。

127.0.0.1:6379> set money 999
OK
# 开启对money的监控
127.0.0.1:6379> WATCH money
OK

但是此时又一个请求,B:请求将money减少了100。

127.0.0.1:6379> get money
"999"
127.0.0.1:6379> DECRBY money 100
(integer) 899

重新回到最开始的A请求,执行一个事务操作。

127.0.0.1:6379> DECRBY money 100
QUEUED
127.0.0.1:6379> DECRBY money 99
QUEUED
# 执行事务时返回了nil
127.0.0.1:6379> EXEC
(nil)

此时查看money的值。

127.0.0.1:6379> get money
"899"

因为监控(watch)money开始之后,该字段的值被其他命令改动了,所以事务将不会被执行。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK