propelorm / Propel2

Propel2 is an open-source high-performance Object-Relational Mapping (ORM) for modern PHP
http://propelorm.org/
MIT License
1.26k stars 398 forks source link

SQLSTATE[08004] [1040] Too many connections in a batch of functional tests #1906

Open papatti opened 2 years ago

papatti commented 2 years ago

I've upgraded my propel1 to Propel2:beta1 in a working project created with Symfony and PropelBundle (sligthly modified version of Skyfox's PropelBundle). Project woks fine! :)

I also have a ton of unit- and tunctional test, including over 200 api tests. They work perfectly well, when using the ConnectionWrapper class, but fail after the first ~200 tests with SQLSTATE[08004] [1040] Too many connections error message having DebugPDO as class.

This is probably because each api call will trigger a full Symfony boot sequence, including PropelBundle's boot function, which creates a new connection each time, until the limit is reached. DebugPDO is a ConnectionWrapper with useDebug=true by default. Same result when ConnectionWrapper was used with useDebug=true.

It can be a problem of PHPUnit, PropelBundle, Propel, or my code. But I think it belongs here.

Theoretically the ConnectionManagerSingle should close existing connections when new configuration is provided (ConnectionManagerSingle::setConfiguration()) by detaching connection objects. If nobody uses them, objects are destroyed, connections are closed. But! I think if debug is set to true, then though the objects are detached from ConnectionManagerSingle::connection, they remain connected to something else (a logger?), thus they are considered as "objects in use", objects are not distroyed, connections are not closed, and they just pile up, until it breaks down.

Long story short: Database connections are closed with ConnectionWrapper, but not closed with DebugPDO or ConnectionWrapper with useDebug=true. And if for some reason (200+ api test in batch) many of them are created with the same properties, existing ones are not reused or closed, their number keeps growing. (checked with beta2, same outcome)

Note: in propel1 there was a !\Propel::isInit() function, this was used in PropelBundle to avoid multiple connection instances, but this has been removed, and the Propel::init() is also deprecated.