一次保存多个实体时如何允许失败?
How to allow failures when saving multiple entities at once?
因此,我可能有数百行需要插入到数据库中。没有验证数据的唯一性。
但是,在数据库中,3 列之间有一个约束条件,即合并后必须是唯一的。有时,这种唯一性失效,导致整个保存操作失败。
有没有办法忽略 Table::saveMany()
调用中的失败并继续保存所有其他记录?也许稍后记录错误,但仍继续保存其余记录,而不是完全使整个操作失败?
不,没有,请查看 API 的描述和 Table::saveMany()
的源代码,它只是将所有实体保存在一个循环中,该循环将停止并回滚事务,以防万一 Table::save()
失败。
The records will be saved in a transaction which will be rolled back if any one of the records fails to save due to failed validation or database error.
https://api.cakephp.org/3.6/class-Cake.ORM.Table.html#_saveMany
如果你想允许失败,那你就得自己处理,保存每条记录,捕获可能的异常,并检查保存操作结果。这是一个简单粗暴的示例,其中 $table
是要保存的 table,$entities
是一个实体数组:
$result = $table->getConnection()->transactional(
function () use ($entities, $table) {
foreach ($entities as $entity) {
try {
$result = $table->save($entity, ['atomic' => false]);
} catch (\PDOException $exception) {
$result = $exception;
}
if ($result !== true) {
// log an error...
}
}
return true;
}
);
另见
您可以采取几种方法来解决这个问题。
而不是使用 Table::saveMany()
做一个循环,只使用 Table::save()
并记录失败的内容,以便您稍后进行调查。
将您的大工作拆分成较小的批次。如果您必须说 1,000 条记录,请将其分成 100 条记录批次,并对每批次使用 Table:saveMany()
。这样,当某些事情失败时,只有当前批次失败,而不是整个保存过程。
有点危险(并且 NOT 推荐)是覆盖 Table::save()
方法,即使它无法存储记录也不会失败。
因此,我可能有数百行需要插入到数据库中。没有验证数据的唯一性。
但是,在数据库中,3 列之间有一个约束条件,即合并后必须是唯一的。有时,这种唯一性失效,导致整个保存操作失败。
有没有办法忽略 Table::saveMany()
调用中的失败并继续保存所有其他记录?也许稍后记录错误,但仍继续保存其余记录,而不是完全使整个操作失败?
不,没有,请查看 API 的描述和 Table::saveMany()
的源代码,它只是将所有实体保存在一个循环中,该循环将停止并回滚事务,以防万一 Table::save()
失败。
The records will be saved in a transaction which will be rolled back if any one of the records fails to save due to failed validation or database error.
https://api.cakephp.org/3.6/class-Cake.ORM.Table.html#_saveMany
如果你想允许失败,那你就得自己处理,保存每条记录,捕获可能的异常,并检查保存操作结果。这是一个简单粗暴的示例,其中 $table
是要保存的 table,$entities
是一个实体数组:
$result = $table->getConnection()->transactional(
function () use ($entities, $table) {
foreach ($entities as $entity) {
try {
$result = $table->save($entity, ['atomic' => false]);
} catch (\PDOException $exception) {
$result = $exception;
}
if ($result !== true) {
// log an error...
}
}
return true;
}
);
另见
您可以采取几种方法来解决这个问题。
而不是使用
Table::saveMany()
做一个循环,只使用Table::save()
并记录失败的内容,以便您稍后进行调查。将您的大工作拆分成较小的批次。如果您必须说 1,000 条记录,请将其分成 100 条记录批次,并对每批次使用
Table:saveMany()
。这样,当某些事情失败时,只有当前批次失败,而不是整个保存过程。有点危险(并且 NOT 推荐)是覆盖
Table::save()
方法,即使它无法存储记录也不会失败。