Quite fascinating fact I just found out while messing up with WebSocket application I am now building using Symfony 4.1 and https://github.com/GeniusesOfSymfony/WebSocketBundle (which is built upon PHP Ratchet).
I wanted to fetch the newest data periodically from the MySQL database for testing purpose using $repository->find(2);
but it always returned the same result even though I was changing data while being subscribed to the WebSocket channel.
After quite a lot of hours of messing with the code and crying, I found out that for some reason Doctrine is caching results (or that is what I think it does).
To test my theory, I created a service that handles fetching from the database with the following code:
/**
* @return mixed
* @throws \Doctrine\DBAL\DBALException
*/
public function fetchNewest()
{
$stmt = $this->em->getConnection()->prepare('SELECT * FROM test WHERE id=2');
$stmt->execute();
return $stmt->fetch();
}
and for some reason, this has worked. Can anyone explain why find(2)
method did not result with the newest data while the raw SQL did?
This is correct, and expected behaviour by an ORM. This is a way to lighten the load on the database.
It is well documented, but most of the time we just skip to the examples and miss it. :)
You would normally not notice this in an application, because of the PHP lifecycle. A request comes in, a response goes out, and everything, shuts down. The next request starts with a clean slate.
If you use a websocket, this never happens, PHP just runs forever (not really, but ideally), and ratchet responds to events.
(OFF: Check out PHP-PM... they have been able to reach a drastic increase in request / s because they subverted the PHP lifecycle).
Lock mode is a solution, but you could also call $em->refresh($entity)
, which triggers a reload from db.