【redis教程】11、redis的事务、锁
redis事务 就是一个命令执行的队列,将一系列预定义的命令包装成一个整体(一个队列)。当执行时,一次性按照添加顺序一次执行,中间不会被打断或者干扰。
一、快速体验redis事务
redis中开启事务使用multi
指令,使用exec
执行事务QUEUED
表示把要执行的指令放进了队列中,exec会把队列中的指令依次顺序执行。
取消事务 使用 discard
指令取消事务。
二、redis事务的注意事项
注意事项1 事务中的指令不要出错,否则事务无法执行,会报错:
这种情况事务中的所有指令都不执行。
注意事项2 事务中的指令语法看上去没有错误,但是实际执行的时候会出错,比如lpush一个String类型的数据:
这种情况没有错误的指令该执行的执行,有错的报个错跳过去了。所以redis对已经执行完毕的数据不会自动回滚,需要程序员自己在代码中实现回滚。 这也是redis的事务在开发中较少使用的原因。
三、基于特定条件的事务执行 ---- 锁
对key添加监控锁,如果exec之前key发生了变化,则终止事务。warch key
上图中客户端2在客户端1监视name之后且执行exec之前改变了name,所以事务中止,返回nil。
unwatch
取消对所有key的监视。
四、基于特定条件的事务执行 ---- 分布式锁
分布式锁的原理 利用setnx key value
来设置一个公共锁,setnx是set if not exists,意思是key如果不存在则可以设置,否则不能设置,和value没有关系。
分布式锁的设计 利用这个特性,就可以设计一个公共锁,执行任务之前先setnx一下,如果返回1,表示获取到了锁,如果返回0,表示没有获取到锁。释放锁直接使用del
删掉就行了。
分布式锁的问题 随之而来的问题,如果有人setnx了一个锁,但是由于各种原因迟迟没有释放,怎么解决?给锁加一个时效就行了。
reids中对一个key加时效:expire key second
pexpire key milliseconds
下面做一下实验:
用户1 获取了一把锁,并设置了时效为20秒,
用户2 在时效结束前获取不到,时效结束,成功获取了锁,
时效时间的长短要根据业务测试后确定。
锁时间设定推荐:最大耗时*120% + 平均网络延迟*110%