解锁使用锁的正确位置
解锁使用锁的正确位置redis是PHP的一个好朋友。在PHP编写业务的过程中,有时使用锁的概念,只有一个人可以操作特定的行为。PHP不能在内存中使用的锁,不能用它和锁,使用数据库进行锁定,并大量消耗。在这个时候,我们通常选择redis作为锁紧机构。
setnx
最简单的数据结构锁定在redis是字符串。在最早的时间,一般用setnx锁定操作,这个命令是:当锁不存在,设置一个值,也许你会记得使用过期增加锁定期满。解锁操作是使用del命令,伪代码如下所示:
如果(redis::setnx(我:锁
使用::我到期(:锁
做某事…
redis::del(我:锁)
}
事实上,有一个问题,而问题是如果setnx到期遇到碰撞等行为,也许锁不会被释放。因此,进一步优化可能存储时间戳判断时间长度的锁。
集
现在官方的建议是使用直接设置来实现锁。我们可以使用set命令来代替setnx,这是继
如果(redis::集(我:锁
做某事…
redis::del(我:锁)
}
上面的代码将我的锁设置为1,并且当且仅当锁不存在时,设置在到期时间为10之后完成。
获取锁的机制是正确的,但是使用del直接删除锁是错误的。它可能导致锁定其他被删除的锁。
例如,我锁锁在10s,但我处理它超过10s。直到10s,锁自动失效,并被别人锁定了。这时,我叫redis:再次:del是删除他人创造的锁。
官方的解锁命令也被推荐。建议使用Lua脚本,得到第一,然后删除
程序变成:
$ =兰德(1, 100000);
函数锁定(){
返回::集Redis(我:锁
}
函数解锁(){
$脚本=
如果redis.call(得到钥匙{ 1 })= argv { 1 }
然后
返回redis.call(删除
其他的
返回0
终点
`
返回:Redis:eval($的剧本,我锁
}
如果(锁定()){
做某事
解锁();
}
在标记是一个随机数,当锁,使用我的:在存款锁定令牌,解锁,得到的,在第一个令牌锁,如果我想删除标记是一样的,锁在我的设置,否则,锁已过期,其他的,我不应该对它做任何事。
所以不要用setnx再次使用设置直接进行锁。
以上是本文的全部内容,希望能对您有所帮助,希望大家多多支持。