sie*_*iej 8 php doctrine symfony doctrine-orm
我正在尝试在事务中进行一些处理并保存有关潜在故障的信息,如下所示:
$conn->beginTransaction();
try
{
$report = $reportRepository->find($id);
$user = $report->getUser();
$specification = new Specification();
$entityManager->persist($specification);
throw new ProcessingWentWrongException();
$entityManager->flush();
$conn->commit();
}
catch(ProcessingWentWrongException $e)
{
$conn->rollback();
// Store error info:
$report->setState('error');
$entityManager->persist($report);
$entityManager->flush(); // all hell breaks loose in here
}
Run Code Online (Sandbox Code Playgroud)
这看起来像一个非常常见的模式,但是Doctrine让它变得非常困难:
flush在catch{}节会尽量坚持既$report和$specification这显然是错误的对象,所以我可以clear的entityManager,但后来......
如果我clear的entityManager,$report通过它不再管理,所以我需要调用$em->merge($report),以使其再次进行管理.显然$user会保持不受管理,所以学说要么表现insert要么抱怨persist cascade.所以我可以是merge()整个图形(很糟糕)或者close是entityManager,但是...
如果我close,entityManager我只能report通过$repo->find($id);- 重新检索实例- 但我不想这样做,这是愚蠢的.
我错过了什么吗?有没有其他方法来实现上述结果?我觉得Doctrine让事情变得简单.
使用两个实体经理。一个用于潜在的不安全操作,另一个用于日志记录/报告。
通常,您不能确定不会发生错误(刷新到数据库之前不会发生某些错误)。一旦发生,实体管理器将关闭营业。
这是我的工作(摘自config.yml):
doctrine:
orm:
default_entity_manager: 'default'
entity_managers:
default:
mappings: { ... }
logging:
mappings: { ... }
Run Code Online (Sandbox Code Playgroud)
对于正常操作,我使用默认的实体管理器,不需要更改您的代码。
对于元操作(如记录批处理导入的进度或结果或类似操作),我明确获取了'logging'管理器并将其用于创建/更新日志记录/报告实体(并且仅用于那些实体)。
| 归档时间: |
|
| 查看次数: |
3880 次 |
| 最近记录: |