愿意付费找答案,thinkphp6使用think-queue高并发下事务报错,如何解决?

thinkphp6使用think-queue在高并发情况下事务报错,Syntax error or access violation: 1305 SAVEPOINT trans2 does not exist
求问如何解决?

public function finishProject(int $projectId, int $winner, int $categoryId, float $odds, float $otherOdds, array $pointsExtra, int $isChampion)
    {
        $result = [
            'status' => \app\common\define\Status::status_failed,
        ];

        $Projects = new \app\job\model\Projects();

        $Projects->startTrans();
        $projectInfo = $Projects->getProjectInfoById($projectId);

        if(empty($projectInfo))
        {
            $Projects->rollback();
            $result['message'] =  '';

            return $result;
        }

        if(!empty($projectInfo['is_getprize']))
        {
            $Projects->rollback();
            $result['message'] =  '';

            return $result;
        }

        if(!empty($projectInfo['is_cancel']))
        {
            $Projects->rollback();
            $result['message'] =  '';

            return $result;
        }

        if(!empty($projectInfo['receive_status']))
        {
            $Projects->rollback();
            $result['status'] = \app\common\define\Status::status_success;
            $result['message'] =  '';

            return $result;
        }

        $prizeStatus = ($projectInfo['winner'] == $winner) ? \app\common\define\Project::WIN_LOSE_WIN : \app\common\define\Project::WIN_LOSE_LOSE;

        $loserPoint = 0;
        $championOdds = '';
        foreach($pointsExtra as $val)
        {
            if($val['id'] == $projectInfo['winner'])
            {
                $loserPoint = $val['point'];
                $championOdds = $val['champion_odds'];
                break;
            }
        }

        if($isChampion && $categoryId == \app\common\define\Game::GAME_CATEGORY_ID_NORMAL)
        {
            $championOdds = json_decode($championOdds, true);

            if(!empty($championOdds))
            {
                ksort($championOdds);
                $projectCreateTime = strtotime($projectInfo['create_time']);

                foreach ($championOdds as $kTime => $val)
                {
                    if($projectCreateTime < $kTime)
                    {
                        $odds = $loserPoint = $val[$projectInfo['winner']];
                        break;
                    }
                }
            }
        }

        $time = time();
        $updateData = array(
            'is_getprize'  => \app\job\model\Projects::STATUS_YES,
            'update_time'  => $time,
            'prize_status' => $prizeStatus,
        );
        if(!$isChampion)
        {
            $updateData['prize_winner'] = $winner;
        }

        if($categoryId == \app\common\define\Game::GAME_CATEGORY_ID_FIX || $categoryId == \app\common\define\Game::GAME_CATEGORY_ID_LIVE)
        {
            $updateData['settlement_odds'] = $projectInfo['odds'];
        }
        else
        {
            $updateData['settlement_odds'] = ($prizeStatus == \app\common\define\Project::WIN_LOSE_WIN) ? $odds : $loserPoint;
        }

        $Company = new \app\job\module\Company();
        $companyInfo = $Company->getCompanyConfigById($projectInfo['company_id']);

        $singleWalletStatus = !empty($companyInfo['single_wallet_status']) && $projectInfo['money_type'] == \app\common\define\Money::MONEY_TYPE_MONEY;

        if($singleWalletStatus)
        {
            $User = new \app\job\module\User();
            $SingleWalletLog = new \app\job\model\SingleWalletLog();
            $UserModel = new \app\job\model\User();

            $userInfo = $UserModel->where('user_id', $projectInfo['user_id'])->find();
            $retryNum = 3;

            if($prizeStatus == \app\common\define\Project::WIN_LOSE_WIN)
            {
                if($categoryId == \app\common\define\Game::GAME_CATEGORY_ID_FIX || $categoryId == \app\common\define\Game::GAME_CATEGORY_ID_LIVE)
                {
                    $amount = $projectInfo['amount'] * $projectInfo['odds'];
                }
                else
                {
                    $amount = $projectInfo['amount'] * $odds;
                }

                $thirdOrderId = uniqid() . mt_rand(1000, 9999);
                $thirdOrderId = strtoupper(highEnCode('SG-' . $thirdOrderId, 'ENCODE'));
                $orderTypeId = \app\job\model\SingleWalletLog::ORDER_TYPE_SG_WALLET_BOUNS;
                $amount = sprintf('%.2f', $amount);

                $otherDesc = [];
                if (!empty($companyInfo['single_wallet_detail']))
                {
                    $Project = new \app\job\module\Project();
                    $otherDesc[] = $Project->formatSingleProject($projectInfo);
                }
                for($i = 0; $i < $retryNum; $i++)
                {
                    $res = $User->singleWalletDeposit($userInfo['username'], $projectInfo['user_id'], $projectInfo['company_id'], $thirdOrderId, $amount, $projectId, $orderTypeId, $time, $otherDesc);

                    if($res['status'] == \app\common\define\Status::status_success)
                    {
                        break;
                    }
                }
                $res['status'] = \app\common\define\Status::status_success;
                $logData = $res['ext'];

                if(false === $SingleWalletLog->insert($logData))
                {

                }

                $updateData['bonus'] = $amount;
            }
        }
        else
        {

            $orders = [
                'user_id'    => $projectInfo['user_id'],
                'other_id'   => $projectId,
                'amount'     => $projectInfo['amount'],
                'exchange_rate' => $projectInfo['exchange_rate'],
                'currency_id'   => $projectInfo['currency_id'],
                'show_scale'    => $projectInfo['show_scale'],
            ];
            
            $MoneyOrders = new \app\job\model\MoneyOrders();
            $orders['order_type_id'] = \app\job\model\MoneyOrders::ORDER_TYPE_PLAY_SUCCESS;
            $res = $MoneyOrders->addOrders($orders);

            if($res['status'] != \app\common\define\Status::status_success)
            {
                $Projects->rollback();
                $result['message'] =  '';
                $result['reback'] = true;

                return $result;
            }

            if($prizeStatus == \app\common\define\Project::WIN_LOSE_WIN)
            {
                $orders = array(
                    'user_id'    => $projectInfo['user_id'],
                    'game_id'    => $projectInfo['game_id'],
                    'other_id'   => $projectId,
                    'exchange_rate' => $projectInfo['exchange_rate'],
                    'currency_id'   => $projectInfo['currency_id'],
                    'show_scale'    => $projectInfo['show_scale'],
                );
                if($categoryId == \app\common\define\Game::GAME_CATEGORY_ID_FIX || $categoryId == \app\common\define\Game::GAME_CATEGORY_ID_LIVE)
                {
                    $orders['amount'] = $projectInfo['amount'] * $projectInfo['odds'];
                }
                else
                {
                    $orders['amount'] = $projectInfo['amount'] * $odds;
                }

                $orders['order_type_id'] = \app\job\model\MoneyOrders::ORDER_TYPE_BOUNS;
                $orders['amount'] = sprintf('%.2f', $orders['amount']); 
                $res = $MoneyOrders->addOrders($orders);

                $updateData['bonus'] = $orders['amount'];

                if($res['status'] != \app\common\define\Status::status_success)
                {
                    $Projects->rollback();
                    $result['message'] =  '';
                    $result['reback'] = true;

                    return $result;
                }
            }
        }

        $updateData['bonus_time'] = $time;

        if(false === $Projects->updateProject($projectId, $updateData))
        {
            if($singleWalletStatus)
            {
                $params = json_encode([$projectId, $updateData]);
            }
            else
            {
                $Projects->rollback();
                $result['message'] =  '';
                $result['reback'] = true;

                return $result;
            }
        }

        $Projects->commit();

        $result['status'] = \app\common\define\Status::status_success;

        return $result;
    }
阅读 3.8k
1 个回答

你这是事务不闭合。关tp啥事

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题