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);
}
}