Nested Set rollback in Doctrine
I'm importing some content into a Nested Tree model, and I'm implementing a Transaction to be sure each object has been saved; and if not, remove it from the tree. I'm using 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();
}
What's happening right now is that if there is any error in the transaction block, all the objects will be deleted. However the tree doesn't return to the original position. This means, that I'll have blank spaces in the 'lft' and 'rgt' positions. The tre开发者_运维问答e would be corrupted then; and fixing a tree with thousands of results can be very expensive.
How I can do to rollback the insertAsLastChildOf(). I think this is something Doctrine should do by itself, but I hope someone can give me a hint.
thanks!
I had to do a manual rollback of the tree when the insert fails, this is the code I've used:
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();
}
And 7 years later someone (me) has similar issue. I found the answer in Doctrine documentation. You just need to put $conn->beginTransaction();
before try
and Doctrine will rollback everything:
// $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();
}
精彩评论