Php Laravel雄辩的质疑赢了';不要退缩

Php Laravel雄辩的质疑赢了';不要退缩,php,mysql,laravel,Php,Mysql,Laravel,我一直想让它工作,但就是不起作用。我有这个函数,我一次将多条记录插入不同的表中,我使用的是事务,但当其中一个查询失败时,它不会回滚 见示例: private function valBankInvestment($bank, $investment, $investment1, $data){ DB::beginTransaction(); $new_bank = DB::table('bank_accounts')->insert($bank); $new_inv =

我一直想让它工作,但就是不起作用。我有这个函数,我一次将多条记录插入不同的表中,我使用的是事务,但当其中一个查询失败时,它不会回滚

见示例:

private function valBankInvestment($bank, $investment, $investment1, $data){
   DB::beginTransaction();
   $new_bank = DB::table('bank_accounts')->insert($bank);
   $new_inv = Investments::create($investment);
   $inv_log = DB::table('investment_logs')->insertGetId($investment1);
   $trader = Traders::create($data);
   if ($new_bank && $new_inv && $inv_log && $trader) {
      DB::commit();
      return true;
   }
   DB::rollBack();
   return false;
}

我想要实现的是,如果这些查询中的任何一个失败,上述函数都应该回滚。请帮我解决这个问题。

您需要捕获异常以回滚事务。如果您不这样做,代码将退出而不调用它

私有函数valBankInvestment($bank,$investment,$investment1,$data){
DB::beginTransaction();
试一试{
$new_bank=DB::table('bank_accounts')->insert($bank);
$new_inv=投资::创建($investment);
$inv_log=DB::table('investment_log')->insertGetId($investment1);
$trader=Traders::创建($data);
}捕获(\异常$e){
DB::rollBack();
返回false;
}
if($new_bank&&$new_inv&&$inv_log&&$trader){
DB::commit();
返回true;
}否则{
DB::rollBack();
返回false;
}
}

@N69S的答案也是正确的,但我喜欢这种非常容易阅读的方式

private function valBankInvestment($bank, $investment, $investment1, $data){

return \DB::transaction(function () use ($bank, $investment, $investment1, $data){
    $new_bank = DB::table('bank_accounts')->insert($bank);
    $new_inv = Investments::create($investment);
    $inv_log = DB::table('investment_logs')->insertGetId($investment1);
    $trader = Traders::create($data);
    return  $new_bank && $new_inv && $inv_log && $trader;
  });
}

当您说
查询失败时
是异常还是在其中一个变量中返回null?您的数据库是MyISAM还是InnoDB?有一些语句
DB::beginTransaction()
不起作用,但我不确定
DB::table()->insert()
是否是其中之一。除此之外,您还需要进行一些调试。如果在
If()
语句之前执行
dd($new\u bank,$new\u inv,$inv\u log,$trader);
,您可以看到所有内容。此外,由于
dd()
终止执行,并且
::commit()
从未被调用,您的事务将不会完成,因此您不会有碎片数据。@N69S是有异常的,但我仍然希望它在出现任何其他故障(如网络问题等)时事务回滚。@FelippeDuarte我的数据库是MyISAM。此异常是否会捕获网络故障或最长执行时间异常?@Sodmond否,它不会。但是如果你有一些沉重的请求,你应该考虑在CLI上使用队列来执行无限的执行时间。@ Sodmond在代码超时使用回滚,你需要配置你的数据库,这样你将被迫锁定EN条目。祝你好运!