目录

Redis的事务讲解

 Redis中的锁


Redis的事务讲解

案例:

redisson没有释放锁 redis释放锁命令_redisson没有释放锁

redisson没有释放锁 redis释放锁命令_redis_02

 

当我们在执行操作时,有别的线程打断了我们执行的操作 。因此,我们需要事务来保证我们操作的完整性。

Redis中的事务就是将命令装入队列中,按进队的顺序执行,具有一次性、顺序性、排他性。

事务的基本操作

·开启事务

multi

作用:开启事务,后续的指令全部加入到事务中

·执行事务

exec

作用:执行事务,也是事务的结束标志,与multi成对出现,成对使用

redisson没有释放锁 redis释放锁命令_缓存_03

 如果在事务定义中发现了错误,应该取消事务

discard

 

redisson没有释放锁 redis释放锁命令_redis_04

discard应该在multi之后,exec之前

事务的注意细节: 

如果我们在事务中写错命令则事务将不会执行 

redisson没有释放锁 redis释放锁命令_redis_05

如果我们在事务中写的指令语法正确但是执行报错则事务将会执行并且无法回滚 

redisson没有释放锁 redis释放锁命令_nosql_06

 需要程序员手动回滚,因此,需要预先记录一下加入事务之前的数据状态

事务的工作流程:

redisson没有释放锁 redis释放锁命令_数据_07

 Redis中的锁

业务场景一:

天猫双十一热卖过程中,对已经售罄的货物追加补货,4个业务员都有权限补货。补货的操作可能是一系列操作,牵扯到多个连续操作,如何保障不会重复操作

业务分析:

①多个客户端可能同时操作同一组数据,并且该数据被修改后,将不适合继续操作

②在操作数据之前锁定要操作的数据,一旦发生变化,终止当前操作

解决方案:

·对key加监视锁,如果在exec执行之前,key发生了变化则终止事务的执行

watch key [key key ...]

·取消所有对key的监视

unwatch

redisson没有释放锁 redis释放锁命令_redis_08

redisson没有释放锁 redis释放锁命令_redis_09

 

redisson没有释放锁 redis释放锁命令_nosql_10

 

 业务场景二:


天猫双11热卖过程中,对已经售罄的货物追加补货,且补货完成。客户购买热情高涨,3秒内将所有商品购 买完毕。本次补货已经将库存全部清空,如何避免最后一件商品不被多人同时购买?【超卖问题】



业务分析:


①使用watch监视key是否变化已经不能解决问题了,现在要监控的是具体的数据


②虽然redis是单线程,但如何避免对个客户端同时对同一个数据进行操作,如何避免不被同时修改



解决方案:分布式锁



·使用setnx设置一个公共锁


setnx lock-key value

setnx:如果设置的key不存在则设置成功,如果设置的key存在则设置失败

·利用setnx的特性,如果设置成功则获得锁

·如果设置失败则排队等待

操作完毕后通过del释放锁

redisson没有释放锁 redis释放锁命令_redisson没有释放锁_11

redisson没有释放锁 redis释放锁命令_redis_12

 

redisson没有释放锁 redis释放锁命令_缓存_13

 

当然,这只是一种设计思想,具有风险性 ,需要手动去释放锁,如果忘记释放锁了呢?那岂不是别人都获取不到锁无法进行下一步的操作。

业务场景三:

当某个用户在使用锁的时候突然电脑宕机了且此时已经获取到锁了,如何解决?

业务分析:

①由于锁的操作由用户控制加锁解锁,必定会存在加锁后未解锁的风险

②不能仅依赖于用户去解锁,应该给出系统级的保底措施

解决方案:

·使用expire为锁key设置有效时间,到时之后不释放锁,放弃锁

expire key seconds
pexpire key milliseconds

redisson没有释放锁 redis释放锁命令_redisson没有释放锁_14

可能此时突然系统崩溃了,锁到时间之后没有释放锁,直接放弃锁

redisson没有释放锁 redis释放锁命令_缓存_15

 

redisson没有释放锁 redis释放锁命令_缓存_16