Laravel Queued Jobs + Doctrine - Fix Mysql Has Gone Away Errors

January 20 2016, 3:34am

With long running processes you can get a 2006 MySQL server has gone away error. This adds a class that calls Doctrine's DBAL Connection's $conn->ping() to see if it's gone away, if so close the connection and let DBAL automatically open a new connection on the next query attempt. This is talked about in the Doctrine's Github repo here. Here's some pseudo code on how to do it:

<?php

namespace Acme\Doctrine\ORM;

use Doctrine\ORM\EntityManager;

class ConnectionSaver
{
    /**
     * Ping the DB server, if connection is lost close it and DBAL will
     * automatically reconnect on the next DB call.
     */
    public function checkDatabaseConnection()
    {
        /** @var \Doctrine\DBAL\Connection */
        $conn = app(EntityManager::class)->getConnection();

        try {
            $ping = $conn->ping();
        } catch (\ErrorException $e) {
            $conn->close();
        }
    }
}

Then inside the command handler you just inject the class and call checkDatabaseConnection() function.

<?php

namespace App\Listeners\Commands;

use Acme\Doctrine\ORM\ConnectionSaver;

class FooHandler
{
    public function __construct(ConnectionSaver $connectionSaver) {
        $connectionSaver->checkDatabaseConnection();
    }