redis是没有锁机制的哟,对于多个用户连接也不存在竞争问题。
但是在进行并发时可能会出现连接超时,连接被阻塞或者是连接被关闭之类的错误。 (推荐学习:Redis视频教程)
一般可以通过在客户端将连接做池化处理(比如使用synchronized,在读写redis时加内部锁),或者在服务器端用redis自带的事务处理命令setnx,来实现锁。
在电商活动中,经常会有“秒杀”的抢购活动,这种场景,服务器通常面临高并发的请求处理。
也就是说,在同一时间,会有大量并发的用户同时去购买某个商品,这时候,就需要保证不会出现过度出售的情况(用户最终购买的商品数量超过实际的商品数量)。
这里就需要应用到redis中加锁和解锁的特性来保证每次的购物操作只有一个用户在进行,避免出现竞争导致脏数据的情况发生。
下面,我们来介绍如何正确使用加锁和解锁。
setnx
redis官方在锁操作上是建议使用set命令来进行,使用方式如下:
if ($redis->set('my:lock', 1, ['NX'])) {
# todo
$redis->del('my:lock');
}
其中
NX — 表示只有key不存在的时候才设置
这个方法有个问题,假如一个客户端获取到锁后发生奔溃或者一直占用着锁不释放,就会导致死锁,使得后续的用户无法获取到锁进行操作。所以这个操作需要设置一个超时时间。
setnx的改进
针对上面方法的问题,我们使用expire方法设置超时时间。但到这里就解决了问题吗?
没有!因为这里expire不是原子操作,如果在操作完setnx后客户端奔溃,这时候就没有成功设置超时时间,同样使得加锁操作面临上面的问题。
if ($redis->set('my:lock', 1, ['NX'])) {
$redis->expire('my:lock', 10);
# todo
$redis->del('my:lock');
}
更多Redis相关技术文章,请访问Redis数据库使用入门教程栏目进行学习!
以上就是redis保存数据的时候会加锁吗的详细内容,转载自php中文网
发表评论 取消回复