阅读 150

redis事务,分布式锁

事务和分布式锁

事务:一组命令集合

主要命令multi 和exec

multi
set a 1
sadd s1 a
......
exec

错误处理

  • (1)语法错误

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a 1
QUEUED
127.0.0.1:6379> set b
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> seta c
(error) ERR unknown command 'seta'
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get a
(nil)
127.0.0.1:6379>

只要有任何一个语法错误,正确的也不会执行

  • (2)运行错误
    比如a是string类型,然后按照hash操作  hset a k1 v1

127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> type a
string
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set n 1
QUEUED
127.0.0.1:6379> hset a k1 v1
QUEUED
127.0.0.1:6379> set m 2
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) OK
127.0.0.1:6379> mget n m
1) "1"
2) "2"
127.0.0.1:6379> type a
string

正确的指令是被执行了,redis事务不支持回滚,所以需要开发者自己处理
开发中规范键名,一般不会出现这种问题

DISCARD取消事务

分布式锁

setnx a:lock 1
expire a:lock 5
del a:lock
为了使setnx和expire能一起执行,而expire的执行又依赖setnx是否成功,显然放事务里是不成立的

setnx和expire组合在一起的原子指令

set a:lock 1 ex 10 nx

以上是这只a:lock 为1 有效期为10s的原子操作

超时问题

Redis 的分布式锁不能解决超时问题,如果在加锁和释放锁之间的逻辑执行的太长,以至于超出了锁的超时限制,就会出现问题。因为这时候第一个线程持有的锁过期了,临界区的逻辑还没有执行完,这个时候第二个线程就提前重新持有了这把锁,导致临界区代码不能得到严格的串行执行。

为了避免这个问题,Redis 分布式锁不要用于较长时间的任务。如果真的偶尔出现了,数据出现的小波错乱可能需要人工介入解决

©著作权归作者所有:来自51CTO博客作者hkui2010的原创作品,如需转载,请注明出处,否则将追究法律责任


文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐