Doctrine2, transactions and lazy-load

June 5, 2013
By

I stumbled in an issue using Doctrine2 transactions inside a Symfony2 app I’m currently developing
I needed a transaction regarding a user property
First attempt has been to retrieve the User object through

public function someAction(Request $request){
$usr= $this->get('security.context')->getToken()->getUser();
$usr = $em->lock($usr, \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE);
....
try{
  $amount = $usr->getSomeProperty();
  if($amount > $okValue){
    $amount--;
  }
  $usr->setSomeProperty($amount);
}

Concurrent requests were correctly blocked until the locking one wasn’t finished, but the $amount value was not correctly modified

After some head banging I found out that recovering the User object from the security context gives you a fully inflated Object so every concurrent request has its own with the value it had prior the transaction being initiated

I modified my code in order to retrieve a User object from the EntityManager

$originalUsr= $this->get('security.context')->getToken()->getUser();
$usr = $em->find('MyBundle:User',$originalUsr->getId(), \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE);

This way when I access the entity and related properties get lazyLoaded, so the value is consistent with the last transaction

Leave a Reply

Your email address will not be published. Required fields are marked *

ERROR: si-captcha.php plugin says GD image support not detected in PHP!

Contact your web host and ask them why GD image support is not enabled for PHP.

ERROR: si-captcha.php plugin says imagepng function not detected in PHP!

Contact your web host and ask them why imagepng function is not enabled for PHP.