Redis锁机制的几种实现方式

Redis加锁分类

redis加锁命令:incr、setnx、set

第一种:incr

思路:key不存在,key值初始化为0并执行incr进行加1。其他用户执行incr操作进行加1时,返回数大于1,说明锁使用中。

	1.A请求获取key,值为1表示获取锁。
	2.B请求获取key,值为2表示获取锁失败。
	3.A执行完代码,删除锁。
	4.B等待一段时间再去请求获取key,值为1获取成功。
	5.B执行完代码,删除锁。
	
	$redis -> incr($key);
	$redis -> exprie($key,$tt1); //设置生成时间为1秒。

第二种:setnx

思路:key不存在,key设置为value,key存在,setnx不做任何动作。

1.A请求设置key的值,设置成功就表示加锁成功。
2.B请求设置key的值,返回失败,表示加锁失败。
3.A执行完代码,删除锁。
4.B等待一段时间再去请求设置key的值,设置成功。
5.B执行代码完成,删除锁。

$redis -> setnx($key,$value);
$redis-> expire($key,$tt1);

第三种:set

incr和setnx的问题:都需要设置key过期,防止请求执行意外退出了,锁没有删除。但是exprie来设置,就不是原子性操作,还需要事务来确保原子性,但是还是有些问题。
思路:set命令,本身就包含了设置过期时间的功能。

1.A请求设置key的值,设置成功就表示加锁成功。
2.B请求设置key的值,设置失败,表示加锁失败。
3.A执行完代码,删除锁。
4.B等待一段时间再去请求设置key的值,设置成功。
5.B执行代码完成,删除锁。

$redis -> set($key,$value,array('nx','ex' => $tt1)); //ex表示秒

其他问题

1.redis加锁失败怎么办?中断请求还是循环请求?

使用循环请求,循环请求获取锁。

2.循环请求的话,如果有一个获取了锁,其他的再去获取锁的时候,是不是容易发生抢锁的可能?

循环请求获取锁的时候,加入睡眠功能,等待几毫秒再执行循环。

3.锁提前过期,A请求没执行完,B请求获取到了锁,A执行完了,会不会上锁的时候把B的锁给删掉?

	在加锁的时候存入的key是随机的,这样的话,每次删除key的时候判断下存入的key里的value和自己存的是否一样。

另外一个锁

官方另外一套加锁的算法。

$servers = [
    ['127.0.0.1', 6379, 0.01],
    ['127.0.0.1', 6389, 0.01],
    ['127.0.0.1', 6399, 0.01],
];

$redLock = new RedLock($servers);

//加锁
$lock = $redLock->lock('my_resource_name', 1000);

//删除锁
$redLock->unlock($lock);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值