Aloha,

Not sure who is aware of this, but I learned this the hard way yesterday:
If a transaction fails with Doctrine2, you might as well output a static page 
and die, because you cannot rely on anything that uses Doctrine2 ORM to still 
work and with all the possible listeners etc you are pretty much screwed.

Doctrine2 EntityManager doesnt offer any method to get the EntityManager back 
into a working state, mainly because there are potentially references from 
proxies that would then point to a bogus EntityManager if the UoW would just be 
cleared. I do not know all the details, but Benjamin is pretty convinced its 
impossible to be able to fix an existing EntityManager instance.

First up of course one should always try and prevent failed transactions. 
However its not always possible to do so without adding elaborate locking 
mechanisms to prevent any sort of race condition. Also in some cases it might 
just be too much overhead to try and verify everything (think importing a large 
XML file).

So when a transaction does fail the only solution is to effectively make a 
totally new EntityManager according to Benjamin.

Now if you use Container injecting this is less of a problem (though still  
problem, more below). If you don't, you basically need to not only make the new 
instance, but you also need to magically find out all the places that follow 
the failed transaction (DB logger, rendered form with DB filled choice fields.

Now if you do inject the Container everywhere and never assign it to a class 
property all you have to do is reset the service. However this is less trivial 
than you might think because of service aliasing:

// reset the EM and all aias
$container->set('doctrine.orm.entity_manager', null);
$container->set('doctrine.orm.default_entity_manager', null);
// get a fresh EM
$em = $this->container->get('doctrine.orm.entity_manager');

Now I am not sure if there is a method that would help me introspect the 
alias's, or if we need a magic method to be able to reset all aliases.

Another approach could be of course to simply always clone the EM before 
starting any transaction, but that doesnt seem all too feasible.

Another approach could be to simply always use a wrapper around the 
EntityManager that gets the Container injected and provides a reset() method.

Thoughts, ideas, prayers? :)

regards,
Lukas Kahwe Smith
[email protected]



-- 
If you want to report a vulnerability issue on symfony, please send it to 
security at symfony-project.com

You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en

Reply via email to