【问题标题】:DB Transaction Laravel not rolling back数据库事务 Laravel 不回滚
【发布时间】:2020-06-05 18:04:12
【问题描述】:

如果满足某个条件,我正在尝试使用 Laravel DB 外观来回滚我的数据库事务。但是我的回滚不起作用。

首先我使用DB::beginTransaction();开始我的数据库事务

其次,我编写了查询以创建以下内容:

  1. 创建新的付款批次
  2. 创建付款批记录
  3. 创建付款批准
  4. 创建付款审批人

然后,我做了一些条件来了解何时回滚或提交我的数据库事务。但是回滚不起作用。示例在我的代码中满足此条件块但从未回滚

if(!$mail_status){
   DB::rollBack();
    return back()->with('error', 'Mail not send to approvers. Try again or contact system administrator.');
}

下面是完整的代码块。

//Start transaction
    DB::beginTransaction();

    try{

        //Run Queries

        //Create a new payment batch
        $batch = Batch::create([
            'uuid' => uniqid(),
            'batch_name' => $batch_config->batch_name,
            'service_code' => Auth::user()->service_code,
            'created_by' => Auth::user()->name,
        ]);

        //Create parameters for new payment batch record
        foreach($batch_record_config as $data){
            $record[] = [
                'batch_id' => $batch->batch_id,
                'payee_name' => $data['payee_name'],
                'bank_id' => $data['bank_id'],
                'bank_name' => $data['bank_name'],
                'account_type' => $data['account_type'],
                'account_number' => $data['account_number'],
                'amount' => $data['amount'],
                'description' => $data['description'],
                'year' => date("Y"),
                'month' => date("F", mktime(0, 0, 0, date("n"), 10)),
                'uuid' => uniqid(),
                'service_code' => Auth::user()->service_code,
                'created_at' => now(),
                'created_by' => Auth::user()->name,
            ];
        }
        $batch_record_status = DB::table('batch_record')->insert($record);

        //Generate new payment approval
        $payment_approval = PaymentApproval::create([
            'uuid' => uniqid(),
            'batch_id' => $batch->batch_id,
            'service_code' => Auth::user()->service_code,
            'created_by' => Auth::user()->name,
            'deleted' => 0,
        ]);

        //Generate payment approvers for the payment approval
        $payment_approvers = [];
        foreach($approval_users as $data){
            $payment_approvers[] = [
                'uuid' => uniqid(),
                'payment_approval_id' => $payment_approval->id,
                'approval_user_id' => $data->id,
                'approval_level_id' => $data->approval_level_id,
                'batch_id' => $batch->batch_id,
                'approval_position_value' => $data->approval_level->approval_position,
                'approval_level_name' => $data->approval_level->approval_level,
                'user_id' => $data->user_id,
                'batch_name' => $batch->batch_name,
                'service_code' => Auth::user()->service_code,
                'approved' => 0,
                'deleted' => 0,
                'created_at' => now(),
                'created_by' => Auth::user()->name,
            ];
        }
        $payment_approvers_status = DB::table('payment_approvers')->insert($payment_approvers); 


        // If DB transcation is successful.
        if($batch && $batch_record_status && $payment_approval && $payment_approvers_status){

            //get the next approvers
            $next_approvers = $this->next_approvals($payment_approval->id);

            if($next_approvers){
                //send mail to the next approvers
                $mail_status = $this->send_approvers_mail($next_approvers,$batch);
                if(!$mail_status){
                    DB::rollBack();
                    return back()->with('error', 'Mail not send to approvers. Try again or contact system administrator.');

                }else{
                    DB::commit();
                    return back()->with('success', 'Batch has being initialized');
                }
            }else{
                DB::rollBack();
                return back()->with('error', 'Approvers not found. Try again or contact system administrator.');
            }  

        }else{
            DB::rollBack();
            return back()->with('error', 'Something went wrong. Try again.');
        }



    }catch(\Exception $e){
        DB::rollBack();
        dd($e);
        return back()->with('error', 'Something went wrong... Contact system administrator. Thanks.');
    }

【问题讨论】:

  • 你需要在最后提交DB::commit();并在try部分使用DB::beginTransaction();
  • 有一个 DB::commit();在检查邮件是否成功的条件内。我还尝试包含 DB::beginTranscation();在 try-catch 中,但也没有工作。
  • DB::beginTransaction 调用不需要在 try/catch 块内,不用担心。哪个回滚不起作用?
  • 所有回滚都不起作用。如果邮件不成功我更感兴趣。

标签: php laravel


【解决方案1】:

你没有提到你的数据库得到提交或抛出一些错误?检查你在邮件函数响应中得到了什么。我认为你在邮件中取得了成功,因为你的 else 条件不是执行任何情况。

【讨论】:

    【解决方案2】:

    我看了你的,正如其他人正确指出的那样,你需要提交交易。我在你的代码中看不到。我知道基本上有两种使用交易的方式。 1.

    \DB::beginTransaction();
        try {
            DB::table('users')->update(['votes' => 1]);
            DB::table('posts')->delete();
        } catch (\Exception $e) {
            $count = 0;
            \DB::rollBack();
            \Log::info(self::LOG_PREFIX . 'Some Msg ', [$e->__toString()]);
        }
    
        \DB::commit();
    

    2.

    DB::transaction(function () {
            DB::table('users')->update(['votes' => 1]);
            DB::table('posts')->delete();
        });
    

    如果您使用第二种方法,则无需进行任何提交,这将在失败时自动回滚。

    我认为错误在你的这一行 $next_approvals = $this->next_approvals($payment_approval->id); 我找不到您的代码中定义的 *next_approvals8 属性,而且您同时使用 Laravel ORM 和原始语句 (PaymentApproval::create & DB::table('batch_record')->insert($record);)

    尝试坚持 1 看看是否可行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-18
      • 2015-08-27
      • 1970-01-01
      • 2019-11-19
      • 2018-05-26
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      相关资源
      最近更新 更多