首页 > 解决方案 > laravel - save vs saveorfail (简而言之,真正的区别)

问题描述

终于是我理解这个概念的时候了,因为我仍然没有得到一些案例。

问题1)返回什么save()?它总是布尔值还是有时会抛出异常?

问题 2)我没有使用任何事件模型。所以我认为save()任何时候都不会返回false。那么它会返回true还是抛出异常?我对吗?

问题3)如果我有这样的事情:

DB::beginTransaction();
try{
  $model1 = new Type();
  $model1->test = 'great';
  $model1->save();

  $model2 = new Type();
  $model2->test2 = 'awesome';
  $model2->save();
  DB::commit();
}catch(Exception $e){
  DB::rollBack();
}

是否有可能没有发生保存但不会引发异常?我在这些模型中没有任何事件。

问题 4)如果问题 3 的答案是“不,这不可能”,那么我为什么需要使用saveOrFail()

我真的很感激,因为我真的找不到任何能深刻解释我所问的东西。

标签: laravellaravel-5eloquentlaravel-4

解决方案


问题1) save()确实可以抛出异常。例如,如果您创建一个带有小数列的模型,例如“成本”,并尝试在该列中保存一个字符串值,两者save()都会saveOrFail()抛出异常。演示:

>>> $item->cost = 'asdas';
>>> $item->save();
 Illuminate/Database/QueryException with message 'SQLSTATE[HY000]: General error: 1366 Incorrect decimal value: 'asdas' for column 'cost' at row 1 (SQL: update ...

问题 2)查看源代码,看起来save()只会false在触发saving,updatingcreating事件返回时返回false

由于您尚未定义任何事件侦听器,理论上是的,您应该只接收true或抛出异常。

问题 3)如果您不听事件,那么不,这是不可能的(至少不可能)。如果抛出异常,保存就不会发生。

问题 4)由于saveOrFail()只是包装在事务中,因此它的用途是在函数save()期间引发任何异常时保持数据库的一致性。确保如果在 期间引发任何异常,则不会保存模型。如果抛出异常,单独无法保证模型没有被修改/保存。save()saveOrFail()save()save()

由于您已经将代码包装在事务中,因此无需使用saveOrFail.

save()对于您的用例,我能想到的最好方法是在单个 if 表达式中调用您的所有模型,并且仅在表达式为true. 这样,您可以在save()返回false或引发异常时满足两者的要求。像这样:

DB::beginTransaction();
try {
  $model1 = new Type();
  $model1->test = 'great';
  
  $model2 = new Type();
  $model2->test2 = 'awesome';
  
  if ($model1->save() && $model2->save()) {
    DB::commit();
  } else {
    DB::rollBack();
  }
} catch(Exception $e){
  DB::rollBack();
}

推荐阅读