加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – Rethrowing部分捕获异常?

发布时间:2020-12-13 17:30:51 所属栏目:PHP教程 来源:网络整理
导读:我有一些代码,在插入远程数据库时偶尔会遇到唯一的索引冲突.由于我需要随机生成但人类可读的值,因此无法避免违规.不幸的是,当发生这种情况时,PDO会抛出一个通用的PDOException,所以我有一个包含这种可憎的循环: do { ... } catch (PDOException $e) { if ($
我有一些代码,在插入远程数据库时偶尔会遇到唯一的索引冲突.由于我需要随机生成但人类可读的值,因此无法避免违规.不幸的是,当发生这种情况时,PDO会抛出一个通用的PDOException,所以我有一个包含这种可憎的循环:

do {
        ...
   } catch (PDOException $e) {
       if ($e->getCode() === '23000') {
          continue; // have another go
      } else {
          throw new Exception("...",1,$e); // reraise
      }
} while(there was an exception);

我认为错误捕获将比搜索然后插入更好,因为使用四位数代码并且在任何时候只有几百个活动代码将会有很少的冲突.

像best practices for catching and re-throwing exceptions?和Rethrow php exception into higher level catch block这样的问题表明,即使在PHP中,这也是不好的做法.我都抓到了一个例外,我99%肯定我要重新抛出,而且我正在使用异常进行流量控制.

有没有更好的方法在PHP中执行此操作,或者是我在数据库中使用存储过程的唯一替代方法,该存储过程在失败时返回错误代码而不是异常.

解决方法

我的结论是,在PHP中没有更好的方法可以做到这一点,所以我将逻辑移到MySQL中,它稍微不那么难看.我正在使用错误处理而不是搜索,因为对于没有冲突的正常情况,这会更快.

首先进行搜索在PHP中会慢得多(两个或多个查询),而在SQL中的正常情况(一个额外查询)稍慢一些,但如果有很多冲突,那么首先进行搜索会更快而不是插入失败.

DECLARE CONTINUE HANDLER FOR 1062 -- duplicate key
    SET @dupe = 1;

SET @dupe = 0;
SET @attemptsLeft = 5;
REPEAT
    SET @user_code = randomString(4);
    INSERT INTO mytable(expires,user_code,users_id)VALUES(p_expires,@user_code,p_users_id);
    SET @attemptsLeft = @attemptsLeft - 1;
    -- if there's a dupe we get the continue handler above
UNTIL @dupe = 0 OR @attemptsLeft <= 0 END REPEAT;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读