3.7.2-Redis事务

Redis事务

Redis基本事务需要用到MULTI和EXEC命令,这种事务可以让一个客户端在不被其他客户端打断的情况下执行多个命令。和关系数据库那种可以在执行过程中进行回滚的事务不同,在Redis中,被MULTI和EXEC命令包围的所有命令会一个接一个的执行,直到所有命令执行完为止。当一个事务执行完毕之后,Redis才会执行下一个事务。

举例说明

Redis中存有一个key为n1,值为1 的数据,现在有多个客户端同时对n1进行incr(加一),decr(减一)操作,如果想要每个客户端n1输出的结果都为1,那么每个客户端操作n1时都需要用到事务(假设客户端A执行了incr,此时另一个客户端B也执行incr,然后客户端A执行decr,此时客户端A得到的n1就为2)

如何操作

在Redis里执行事务,首先执行MULTI命令,然后输入想要在事务中执行的命令,最后再执行EXEC命令。当Redis接收到客户端MULTI命令时,会将客户端发送的命令放到一个队列中,当客户端发送EXEC命令时,Redis会在不被打断的情况下,一个接一个的执行存储在队列中的命令。

127.0.0.1:6379> set n1 1
OK
127.0.0.1:6379> get n1
"1"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr n1
QUEUED
127.0.0.1:6379> decr n1
QUEUED
127.0.0.1:6379> exec
1) (integer) 2
2) (integer) 1

如果在事务中有错误的命令,那么事务不会执行成功,例如:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set n1 2
QUEUED
127.0.0.1:6379> get1 n1
(error) ERR unknown command `get1`, with args beginning with: `n1`,
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

如何手动取消事务(使用DISCARD命令):

127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr n1
QUEUED
127.0.0.1:6379> discard
OK

使用Redis实现乐观锁

  • 悲观锁:线程每次在处理共享数据时都会上锁,其他线程想处理数据就会一直阻塞直到获得锁。适合写操作比较多的场景
  • 乐观锁:线程每次在处理共享数据时都不会上锁,在更新时会通过数据的版本号登记制判断其他线程有没有更新数据。适合读多写少
举例说明:

Redis中存有key为money,value为100的数据,现同时有两个客户端对数据money进行操作,客户端A减去80后并不执行exec命令,此时客户端B减去50后执行exec命令(因为此时客户端A并未执行exec命令,所以金额还为100)
客户端A(金额大于80):

127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 80
QUEUED

客户端B(金额大于50):

127.0.0.1:6379> decrby money 50
(integer) 50
127.0.0.1:6379> get money
"50"

客户端B执行完后客户端A再执行exec命令:

127.0.0.1:6379> exec
1) (integer) -30

此时money数据显然不合理,想要让客户端A执行减去80操作时感知到money值发生变化则需要用到WATCH(监听)命令

127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 80
QUEUED
##在客户端B执行完后执行exec,事务执行失败,此时money值为50而不是-30
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get money
"50"

此时如果想要对money继续操作则需要先使用UNWATCH命令解锁后再WATCH(加锁)
参考:
https://blog.youkuaiyun.com/qq_41574321/article/details/108221685
https://www.bilibili.com/video/BV1S54y1R7SB?p=22

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值