解锁使用锁的正确位置

解锁使用锁的正确位置



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再次使用设置直接进行锁。

以上是本文的全部内容,希望能对您有所帮助,希望大家多多支持。