Откат вложенного набора в Doctrine
Я импортирую некоторый контент в модель Nested Tree и внедряю транзакцию, чтобы убедиться, что каждый объект был сохранен; и если нет, удалите его из дерева. Я использую Doctrine 1.1.6.
// Start the transaction
$conn = Doctrine_Manager::connection();
try {
$conn->beginTransaction();
// add it as a child of the suburb
$object->getNode()->insertAsLastChildOf($parent);
...
// save related objects
...
$conn->commit();
} catch(Doctrine_Exception $e) {
$conn->rollback();
}
Сейчас происходит то, что в случае ошибки в блоке транзакции все объекты будут удалены. Однако дерево не возвращается в исходное положение. Это означает, что у меня будут пробелы в позициях 'lft' и 'rgt'. Тогда дерево будет повреждено; и исправление дерева с тысячами результатов может быть очень дорогим.
Как я могу сделать, чтобы откатить insertAsLastChildOf(). Я думаю, что это то, что доктрина должна делать сама по себе, но я надеюсь, что кто-то может дать мне подсказку.
Спасибо!
2 ответа
При неудачной вставке мне пришлось выполнить откат дерева вручную, вот код, который я использовал:
try {
$conn->beginTransaction();
// add it as a child of the suburb
$obj->getNode()->insertAsLastChildOf($parent);
$rgt = $obj->rgt;
...
...
}catch(Doctrine_Exception $e) {
$conn->rollback();
$result = Doctrine_Query::create()->update('Model p')
->set('p.lft = p.lft - 2')
->set('p.rgt = p.rgt - 2')
->where('p.rgt > ?', $rgt)
->addWhere('p.root_id = ?', $parent->root_id)
->execute();
}
И через 7 лет у кого-то (меня) возникла похожая проблема. Я нашел ответ в документации Учения. Вам просто нужно поставить $conn->beginTransaction();
до try
и Доктрина все откатит
// $em instanceof EntityManager
$em->getConnection()->beginTransaction(); // suspend auto-commit
try {
$object->getNode()->insertAsLastChildOf($parent);
$em->flush();
$em->getConnection()->commit();
} catch(Doctrine_Exception $e) {
$em->getConnection()->rollBack();
}