Redis事务和锁
Redis事务
简介
Redis中的事务是一组命令执行的队列。事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都一次性执行,要么都不执行。当执行时,一次性按照顺序执行,中间过程不能被干扰
事务的基本操作
开启事务 multi
设置事务的开启,后续的指令都加入到这个队列当中,执行事务
exec
事务的结束,执行所有事务并返回结果。
取消事务 discard
事务定义过程中出现问题,即时取消事务
事务的工作流程
操作过程
没有开启事务,无法获取当前设置数据
另一台客服端设置的是set name yu
开启事务之后,所有步骤都一致
事务设置错误,取消当前事务
事务注意事项
1.如果输入指令有语法错误,整体事务中所有的命令都不会执行
2.如果输入的指令没有语法错误,命令执行错误,正确的命令会执行,运行错误的命令不会被执行。如果在实际编码中,已经执行命令的数据不会回滚,需要自己手动回滚。
锁
应用场景:(控制批量任务执行) 多个客户端有可能同时操作同一组数据,并且该数据一旦被操作修改后,将不适用于继续操作 ,在操作之前锁定要操作的数据,一旦发生变化,终止当前操作。
添加监视锁
watch
,在执行事务结束之前,如果key里面的数据发生了改变,终止事务执行。
unwatch
取消对所有 key 的监视
实操
我在执行exec结束事务之前,在另一个客服端修改了aa的值,发现事务结束获得的值是空。
在事务开启之后,不能监控key,取消监控之后,开启事务,添加数据之后,在另一台客户端修改数据aa,然后结束事务,发现数据没有被更改。
添加分布式锁
应用场景:避免最后一件商品不被多人同时购买,也是淘宝中的超卖问题,使用watch监控一个key判断改变已经不能解决问题,此处要监控的是具体数据,在这里可以设置一个公共锁。
设置公共锁 setnx
lock-key value
若果返回值为0,则设置失败,无则返回成功,返回为1的话可以操作,失败的话需要等待。操作完之后需要用del指令释放锁。
实操
第一步,添加数据,第二步,使用setnx上锁,第三步,购买商品-1,第四步,删除锁。
如果在另一台客服端操作的话,已经上过锁之后,本台客服端无法上锁,直到对方删除锁之后,方可操作。
分布式锁该进操作
由于控制加锁解锁操作全部都由用户自己完成,一定存在未解锁的风险 , 需要解锁操作不能仅依赖用户控制,系统设计应该留下一个应急处理方案
解决方案
使用 expire 为锁key添加时间限定,自动释放锁
expire lock-key second
pexpire lock-key milliseconds
设置分布式锁要根据特定的场合而定, 例如:持有锁的操作最长执行时间127ms,最短执行时间7ms。 测试百万次最长执行时间对应命令的最大耗时,测试百万次网络延迟平均耗时 。 锁时间设定推荐:最大耗时120%+平均网络延迟110% 。如果业务最大耗时<<网络平均延迟,通常为2个数量级,取其中单个耗时较长即可。
第一步,添加数据,第二步,上锁,第三步,为锁设置时间,等待时间过了,另一台客服端即可设置锁。