Откат вложенного набора в Doctrine - PullRequest
2 голосов
/ 19 февраля 2010

Я импортирую некоторый контент в модель 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 ]

1 голос
/ 20 февраля 2010

Мне пришлось выполнить откат дерева вручную при неудачной вставке, вот код, который я использовал:

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();
}
0 голосов
/ 27 июля 2017

И через 7 лет у кого-то (меня) возникла похожая проблема. Я нашел ответ в Документация доктрины . Вам просто нужно поставить $conn->beginTransaction(); перед try и Doctrine откатит все:

  // $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();
  }
...