redis事物,锁机制,分布式锁机制
Redis事务
无论大小项目,相信事务是不容忽视的,下面我们对redis事务展开讨论。我们很熟悉mysql事务,对redis的事务也就简单了,首先我们对比一下两种事务的异同:
redis事务是怎么工作的呢?我们举个例子:
当我们启动事务后,假设账户有300元,发现返回一个QUEUED,队列,这是为什么?其实在redis中会用队列来保存用户的事务操作,当exec提交后会按照顺序执行每一条命令,所以当启动事务,每执行一个操作,它并不是真正的执行,而是暂时放在这个队列,等待事务的提交。
思考:如果在提交事务后执行时中间有一个语句执行出错会怎样呢?
1、语法问题
中间有语法错误,所有事务会discard取消。
2、运行错误
Redis事务没有事务回滚功能,所以使用者必须自己收拾烂摊子,不过正是因此,Redis事务更加简洁快速。
WATCH、UNWATCH、DISCARD命令
上面的例子我们知道,事务中的命令要全部执行后才能获取每个命令的结果,但是如果一个事务中的命令依赖它上一个命令的结果怎么办?这就要引进Redis事务一成员:WATCH命令。
WATCH可以监控一个或多个键,一旦其中有一个键被修改或删除,之后的事务就不会执行,监控一直持续到EXEC(执行完后被监控的键自动被UNWATCH)。举个例子:
执行multi前将mykey改为2,执行multi开始事务后将mykey改为3,结果事务中的命令没有执行。
如果在multi执行前UNWATCH取消对mykey的监控,则事务中的命令就会执行:
DISCARD命令会在multi之后exec之前清空事务队列,然后从事务状态退出。
注意事项
1.Redis的事务没有关系数据库事务提供的回滚(rollback),所以开发者必须在事务执行失败后进行后续的处理;
2.如果在一个事务中的命令出现错误,那么所有的命令都不会执行;
3.如果在一个事务中出现运行错误,那么正确的命令会被执行。
Redis分布式锁
上面介绍的三个命令,只会在数据被其他客户端抢先修改的情况下,通知执行这些命令的客户端,让它撤销对数据的修改操作,并不能阻止其他客户端对数据修改,所以称为乐观锁。
我们来看个例子:
我们假设大白有300dolar,现在剩下一张机票。
multi
set baymax:money 300
set ticket 1
如果这时有个超大白抢先一步抢到了这张票:
decr ticket
这时如果大白继续买票会发生什么情况?
decrby baymax:money 300
decr ticket
exec
如果单看以上代码,我们发现ticket变为-1,这时绝对不许发生的,我们该怎么办呢?这时就用到redis的乐观锁了,它使用watch命令监控指定key,如果key被改动,则事务取消,这样就可以避免ticket变为-1的问题了。
watch ticket
该乐观锁不具备可扩展性,当客户端尝试完成一个事务的时候,可能因为事务执行失败反复重试,保证数据准确性很重要,但是当负载变大的时候,使用乐观锁并不完美,这时就需要Redis实现分布式锁。
分布式锁是控制分布式系统之间同步访问共享资源的一种方式,在访问这些资源的时候,往往需要互斥来保持一致性,这种情况需要用到分布式锁。
死锁
思考:如果一个持有锁的客户端失败或崩溃了不能释放锁,该怎么办?
两种方式给锁设置过期时间:
1、执行命令:“setnx 键名 过期时间”
2、设置锁的expire时间,让Redis删除锁。
---------------------
作者:种下星星的日子
来源:****
原文:https://blog.****.net/hongwei15732623364/article/details/81047751
版权声明:本文为博主原创文章,转载请附上博文链接!