6

We have a process that runs within our Magento installation that:

  1. Bootstraps Magento
  2. Performs some actions which involve writing to a table in mysql
  3. Connects to a remote API, which takes a long time to respond (20mins +)
  4. Attempts to write more information to a table in mysql

The problem is, that due to the long time taken for the remote API to respond, the MySQL server has sometimes 'Gone Away' by the time we attempt to perform step 4. The simplest solution to this is to simply increase the wait_timeout for MySQL, but this feels like a hacky solution.

Is there a way from within Magento to close then reopen the database connection? Or even just force a reconnect after step 3? I tried to dig into it, but the actual instantiation of the connection seems (as with many things in Magento) deeply buried. I'm therefore unsure exactly how I might force a reconnect.

  • have you tried just reconnecting to the database using Zend_Adapter class? – simonthesorcerer Nov 27 '13 at 10:48
8

Yes, you can. Assuming you open the connection with something like this:

$db = Mage::getSingleton('core/resource')->getConnection('core_read');

You can close the connection with this:

$db->closeConnection();

And then re-open it with this:

$db->getConnection();

When I need to make an api call that could take a long time, I close the connection first, then use getConnection to open it again afterwards, which has solved the "mysql server has gone away" problem for me.

  • I'm not manually getting a connection, merely working with models. Presumably these use the same connection internally, since it's a singleton I can probably get hold of it that way. I'll give it a go, thanks. – Peter O'Callaghan Jan 3 '14 at 13:58
3

What worked for me was to get all open connections from the resource singleton and close them:

private static function disconnectMysql()
{
    /** @var Zend_Db_Adapter_Abstract $connection */
    foreach (Mage::getSingleton('core/resource')->getConnections() as $name => $connection) {
        if ($connection instanceof Zend_Db_Adapter_Abstract) {
            $connection->closeConnection();
        }
    }
}

You don't need to explicitly open them again, the next query will reopen the connection automatically.

Update: if you rely upon <initStatements>SET NAMES utf8</initStatements> (you probably do), it is not enough to close the connections because the init statements will not be executed on reconnection. You have to actually unset the connection objects so that they will be recreated. The only way I found without rewriting core methods is to reset the whole core/resource singleton after disconnecting:

Mage::unregister("_singleton/core/resource");

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.