How to use Master/Slave doctrine2 configurations from Symfony2 Console commands

doctrine-orm, mysql, php, symfony

Solution

You have to make sure your command doesn't call any action that lets doctrine choose the master connection.

Important for the understanding of the `MasterSlaveConnection` should be how and when it picks the slave or master.

- picks Slave if Master was never picked before and ONLY if 'getWrappedConnection' or 'executeQuery' is used.

- Master picked when 'exec', 'executeUpdate', 'insert', 'delete', 'update', 'createSavepoint', 'releaseSavepoint', 'beginTransaction', 'rollback', 'commit', 'query' or 'prepare' is called.

- If master was picked once during the lifetime of the connection it will always get picked afterwards.

- One slave connection is randomly picked ONCE during a request.

(MasterSlaveConnection API)

Problem

I'm using the Doctrine2 master/slave configuration in Symfony2 to scale my application across a single master database and several read-only (replicated) slaves. This works perfectly from within my application and Doctrine2 sensibly uses the slave for read-only queries and the master for write operations. If in one of my controllers, I wrote: ``` $em = $this->get('doctrine')->getManager(); var_dump($em->getConnection()->isConnectedToMaster()); ``` `isConnectedToMaster()` returns `false` - which I would expect since the slave is connected to by default. This is also the case if I run this code inside a `WebTestCase` However if I wrote the exact same code inside a Symfony console command (ContainerAwareCommand): ``` $em = $this->getContainer()->get('doctrine')->getManager(); var_dump($em->getConnection()->isConnectedToMaster()); ``` `isConnectedToMaster()` returns true. Which means the master is selected as the default. I can't find out how to stop the default connection being master from console commands. Which means if I want to run some non-critical, heavy data processing tasks from the console - they all hit the master (bad) not one of the slaves (good). Anyone know how I can make Doctrine2 use the slave by default from the console? Or know why it always defaults to the master? ANSWERED: Thanks to nifr who set me on the right course - I found that my problem was because I was using JMS\JobQueueBundle (which replaces the Application used by app/console with an altered one which must connect to the MasterSlaveConnection in a way which forces the "master" to be chosen). When I commented out the ``` use JMS\JobQueueBundle\Console\Application; ``` in `app/console`, the slave was correctly selected in my console test. Thanks

Original source

Related problems