Redis防止业务重复处理的应用

Redis经常被用来处理可能会重复执行的操作场景,比如防止前端重复提交、接口超时重试、消息重复推送等场景,以保证幂等。

Redis主要是基于 setnx 命令来实现的,该命令设置一个指定的 key 并指定超时时间,

当设置成功时返回 1,同时执行后续的业务逻辑;

当设置失败时返回 0,可直接返回;

最后 del 邮件这个 key 防止长时间锁redix。

但是可能会出现A线程成功执行setnx和业务逻辑代码时,B线程恰好执行失败并把redix锁给删除了,C线程又因为无锁而成功执行,导致幂等失效,解决办法就是将 setnx 放到 try 之前执行。

debug() {
	$redis = new Redis();
	if( ! $redis->setnx(key, 2) ){
		return error(-1, "请勿重复操作");
	}
	
	try {
		//业务逻辑代码...
	}
	finally {
		$redis->del(key);
	}
}