如何封装带Try-Catch与重试逻辑的可复用For循环?
解决方案:封装可复用的数据库重试逻辑
Hey there! You want to wrap that retry-on-QueryException logic into a reusable function so you only need to pass in your actual business code—smart move. Here's a clean way to implement this:
1. 创建可复用的重试函数
你可以把这个函数定义为全局辅助函数(添加到项目的helpers.php文件中),或者放在服务类里,根据你的代码结构选择即可:
function loop(callable $callback, int $maxAttempts = 2) { for ($attempt = 0; $attempt < $maxAttempts; $attempt++) { try { // 执行传入的业务逻辑,同时保留返回值 return $callback(); } catch (\Illuminate\Database\QueryException $e) { // 如果是最后一次尝试,不再重试,直接抛出异常 if ($attempt === $maxAttempts - 1) { throw $e; } // 否则继续循环重试 } } }
代码说明:
callable $callback: 接收一个闭包参数,你需要执行的业务逻辑(比如创建用户、更新数据)都写在这里面int $maxAttempts = 2: 默认设置为2次尝试(1次初始执行 + 1次重试),调用时可以根据需求自定义次数- 使用
return $callback()确保业务逻辑的返回值能传递回调用处 - 仅捕获
QueryException,其他异常会直接抛出,和你原来的代码行为保持一致
2. 按你想要的方式调用
现在你可以完全摆脱重复的循环和捕获代码,只需要传入业务逻辑即可:
// 示例1:创建用户 loop(function() { return User::create([ 'name' => 'user name' ]); }); // 示例2:更新数据 loop(function() { return User::where('id', 42)->update([ 'email' => 'updated@example.com' ]); }); // 示例3:自定义尝试次数(比如总共3次尝试) loop(function() { return Order::create(['total' => 99.99]); }, 3);
3. 可选进阶优化:让函数更灵活
如果需要适配更多场景,可以扩展函数支持自定义捕获异常类型和重试延迟:
function retryOnException(callable $callback, int $maxAttempts = 2, array $allowedExceptions = [\Illuminate\Database\QueryException::class], int $retryDelayMs = 0) { for ($attempt = 0; $attempt < $maxAttempts; $attempt++) { try { return $callback(); } catch (\Throwable $e) { // 检查当前异常是否在允许重试的列表中 $shouldRetry = collect($allowedExceptions)->contains(fn($exceptionClass) => $e instanceof $exceptionClass); // 如果不允许重试,或者是最后一次尝试,直接抛出异常 if (!$shouldRetry || $attempt === $maxAttempts - 1) { throw $e; } // 如果设置了延迟,等待后再重试 if ($retryDelayMs > 0) { usleep($retryDelayMs * 1000); // 毫秒转微秒 } } } }
调用进阶版的示例:
// 允许在QueryException和PDOException时重试,共3次尝试,每次间隔500毫秒 retryOnException(function() { // 你的数据库操作逻辑 }, 3, [\Illuminate\Database\QueryException::class, \PDOException::class], 500);
这样你就拥有了一个既贴合原始需求,又能灵活扩展的复用工具啦。
内容的提问来源于stack exchange,提问作者Muhammad Ahsan Abrar
相关产品推荐
相关产品推荐

