On 5/2/11 12:04 PM, Benjamin Eberlei wrote:
I will happily assist with ideas, i am just short on time at the moment.
:-(
I have a first POC here:
https://github.com/fabpot/symfony/commit/cfed1e76541f1382da53022577a141f67559a410
This commit does two things by introducing a new Doctrine Registry class:
* It allowed for the removal of some DIC parameters (replaced with
method calls) -- this is a big win as parameters are always a bit
magical (as you cannot easily guess their names)
* The Registry knows everything about your connections and entity
managers (in the scope of a given Container of course). So, it can
easily reload an entity manager if you need to and replace it in the
service container.
I have extending the Doctrine EntityManager to allow easy access to the
reload() method:
$em->getConnection()->beginTransaction(); // suspend auto-commit
try {
//... do some work
} catch (Exception $e) {
$em->getConnection()->rollback();
// call reload() instead of close()
$em = $em->reload();
}
and I've submitted a PR to change the current Doctrine EntityManager to
allow inheritance: https://github.com/doctrine/doctrine2/pull/51. As
noted, it was rejected once, but I still fail to understand why.
If overriding the entity manager is not desirable, then the interface
will be less intuitive for the developer (but this will still work):
$em = $container->get('doctrine.registry')->reload($em);
Thoughts?
Fabien
On Mon, 02 May 2011 11:57:38 +0200, Fabien Potencier wrote:
On 3/26/11 10:43 AM, Lukas Kahwe Smith wrote:
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? :)
You have the same problem if you use transactions in your tests and
if you are explicitly testing failures.
Anyway, I will work on this issue now as this is one of the biggest
possible pain point when using Doctrine2 with Symfony2.
Fabien
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