开启事务后报错无法捕获异常

fyang

问题描述

开启了DB事务操作,然后在try里调用了方法,调用的方法报错了,抛出 RuntimeException 异常

程序代码

$result = false;
DB::beginTransaction();
        try {
            $validate = new \app\validate\BookApplyValidate();
            if (!$validate->scene('pass')->check($params)) {
                throw new ParamsException((string) $validate->getError());
            }

            $FriendService = new FriendService();
            $applyInfo = $FriendService->findApply(['id' => $params['apply_id']]);//就这个报错了,抛出 RuntimeException 异常

        } catch (ParamsException $e){
            DB::rollBack();
            return Response::buildFailed($e->getCode(),$e->getMessage());
        } catch (OperateException $e){
            DB::rollBack();
            return Response::buildFailed($e->getCode(),$e->getMessage());
        } catch (QueryException $e) {
            DB::rollBack();
            return Response::buildFailed(ReturnCode::DB_ERROR,'数据操作异常,请联系管理员',['msg'=>$e->getMessage()]);
        } catch (\Exception $e) {
            DB::rollBack();//上面没有捕获的话,应该会被这个异常基类捕获呀
            return Response::buildFailed(ReturnCode::EXCEPTION, '网络异常,请检查网络');
        }

        if ($result){
            DB::commit();
            return Response::buildSuccess([], '操作成功');
        }else{
            DB::rollBack();
            return Response::buildFailed(ReturnCode::INVALID, '操作失败,请稍后再试');
        }

报错信息

RuntimeException: Uncommitted transactions found in P:\wwwroot\self_wwwroot\webman\project\backend\vendor\webman\log\src\Middleware.php:120
Stack trace:
#0 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\webman-framework\src\App.php(309): Webman\Log\Middleware->process()
#1 P:\wwwroot\self_wwwroot\webman\project\backend\app\middleware\Cors.php(20): Webman\App::Webman\{closure}()
#2 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\webman-framework\src\App.php(309): App\middleware\Cors->process()
#3 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\webman-framework\src\App.php(531): Webman\App::Webman\{closure}()
#4 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\webman-framework\src\App.php(128): Webman\App::findRoute()
#5 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\workerman\Connection\TcpConnection.php(638): Webman\App->onMessage()
#6 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\workerman\Events\Select.php(311): Workerman\Connection\TcpConnection->baseRead()
#7 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\workerman\Worker.php(2467): Workerman\Events\Select->loop()
#8 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\workerman\Worker.php(1453): Workerman\Worker->run()
#9 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\workerman\Worker.php(1396): Workerman\Worker::forkWorkersForWindows()
#10 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\workerman\Worker.php(560): Workerman\Worker::forkWorkers()
#11 P:\wwwroot\self_wwwroot\webman\project\backend\vendor\workerman\webman-framework\src\support\App.php(124): Workerman\Worker::runAll()
#12 P:\wwwroot\self_wwwroot\webman\project\backend\start.php(4): support\App::run()
#13 {main}
965 2 0
2个回答

powerbowen

这样试试?


        try {
            //code
        } catch (ParamsException $e){
            DB::rollBack();
            return Response::buildFailed($e->getCode(),$e->getMessage());
        } catch (OperateException $e){
            DB::rollBack();
            return Response::buildFailed($e->getCode(),$e->getMessage());
        } catch (QueryException $e) {
            DB::rollBack();
            return Response::buildFailed(ReturnCode::DB_ERROR,'数据操作异常,请联系管理员',['msg'=>$e->getMessage()]);
        } catch (\RuntimeException $e) {
             DB::rollBack();
            return Response::buildFailed(ReturnCode::DB_ERROR,'数据操作异常,请联系管理员',['msg'=>$e->getMessage()]);
        }  catch (\PDOException | \Exception | \Error $e) {
             DB::rollBack();
            return Response::buildFailed(ReturnCode::DB_ERROR,'数据操作异常,请联系管理员',['msg'=>$e->getMessage()]);
        } catch (\Throwable $e) {
            DB::rollBack();
            return Response::buildFailed(ReturnCode::EXCEPTION, '网络异常,请检查网络');
        }
  • fyang 2022-11-14

    我加多了个 Error 分支,才可以捕获

  • powerbowen 2022-11-14

    你的索引异常未必能捕获到,增加相应的 PDOException,RuntimeException先,因为是自己的搞的,然后 \Exception | \Error 这个兜底错误和其它基本异常,Throwable 这个做最终兜底

  • fyang 2022-11-14

    好吧,确实需要兜底的

  • powerbowen 2022-11-14

    https://www.workerman.net/doc/webman/exception.html
    这里有个统一的异常处理捕获,可以做最终兜底,你可以看一看配一配

  • fyang 2022-11-14

    好的,谢谢

keytehu

兜底得用 catch (\Throwable $e)catch (\Exception $e) 捕获不了Error错误

  • fyang 2022-11-14

    我想了下,如果所有代码都未能捕获这个异常,那这个肯定是代码错误了,每个分支去写 Throwable 也没有意义了,干脆直接配置每个模块异常处理类去做统一的500处理

年代过于久远,无法发表回答
🔝