Managing PostgreSQL transactions for concurrency
Taking Craig's suggestion, I've had the following running in a test environment for one week with no issues:

public function runInTransaction(callable $callable)
{
    $success = false;
    $count = 0;
    $this-&gt;beginTransaction($isolationLevel);
    $this-&gt;exec("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
    try {
        while (!$success &amp;&amp; $count &lt; 5) {
            try {
                $callable();
                $success = $this-&gt;commit();
            } catch (\PDOException $e) {
                // Catch concurrency issues and retry after
                // random scaled back-off delay.
                if ($e-&gt;getCode() == '40001' || $e-&gt;getCode() == '40P01') {
                    // Serialized transaction failure or deadlock.
                    usleep(rand(100, 200) * ($count + 1));
                } elseif ($e-&gt;getCode() == '25P02') {
                    // "In failed sql transaction."
                    $this-&gt;rollback();
                    usleep(rand(100, 200) * ($count + 1));
                    $this-&gt;beginTransaction($isolationLevel);
                } else {
                    throw $e;
                }
            }
            $count++;
        }
    } catch (\Exception $e) {
        if ($this-&gt;inTransaction()) {
            $this-&gt;rollback();
        }
        throw $e;
    }
    if (!$success) {
        throw new \RuntimeException("Could not commit transaction");
    }
}