在magento的pdo_mysql适配器中缺少“超过锁定等待超时”处理?

时间:2012-07-06 16:20:09

标签: php mysql magento timeout

如果我比较两个Magento适配器类 Varien_Db_Adapter_Mysqli Varien_Db_Adapter_Pdo_Mysql ,我可以在方法 raw_query 的查询异常处理中找到一些差异。< / p>

<?php

class Varien_Db_Adapter_Mysqli extends Zend_Db_Adapter_Mysqli
{

//....

/**
 * Run RAW Query
 *
 * @param string $sql
 * @return Zend_Db_Statement_Interface
 */
public function raw_query($sql)
{
    $timeoutMessage = 'SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded;      try restarting transaction';
    $tries = 0;
    do {
        $retry = false;
        try {
            $this->clear_result();
            $result = $this->getConnection()->query($sql);
            $this->clear_result();
        } catch (Exception $e) {
            if ($tries < 10 && $e->getMessage() == $timeoutMessage) {
                $retry = true;
                $tries++;
            } else {
                throw $e;
            }
        }
    } while ($retry);

    return $result;
}

//....

}

如果我在Varien_Db_Adapter_Pdo_Mysql中将它与相等方法进行比较,我会发现另一个错误处理。它不会检查超时,但会检查丢失的连接。

<?php

class Varien_Db_Adapter_Pdo_Mysql  extends Zend_Db_Adapter_Pdo_Mysql implements Varien_Db_Adapter_Interface
{

//....


/**
 * Run RAW Query
 *
 * @param string $sql
 * @return Zend_Db_Statement_Interface
 * @throws PDOException
 */
public function raw_query($sql)
{
    $lostConnectionMessage = 'SQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query';
    $tries = 0;
    do {
        $retry = false;
        try {
            $result = $this->query($sql);
        } catch (Exception $e) {
            // Convert to PDOException to maintain backwards compatibility with usage of MySQL adapter
            if ($e instanceof Zend_Db_Statement_Exception) {
                $e = $e->getPrevious();
                if (!($e instanceof PDOException)) {
                    $e = new PDOException($e->getMessage(), $e->getCode());
                }
            }
            // Check to reconnect
            if ($tries < 10 && $e->getMessage() == $lostConnectionMessage) {
                $retry = true;
                $tries++;
            } else {
                throw $e;
            }
        }
    } while ($retry);

    return $result;
}

//....

}

这是对的吗?检查两种失败案例会不会更好?

示例:

/**
 * Run RAW Query
 *
 * @param string $sql
 * @return Zend_Db_Statement_Interface
 * @throws PDOException
 */
public function raw_query($sql)
{
    $lostConnectionMessages = array(
        'SQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query',
        'SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction',
    );
    $tries = 0;
    do {
        $retry = false;
        try {
            $result = $this->query($sql);
        } catch (Exception $e) {
            // Convert to PDOException to maintain backwards compatibility with usage of MySQL adapter
            if ($e instanceof Zend_Db_Statement_Exception) {
                $e = $e->getPrevious();
                if (!($e instanceof PDOException)) {
                    $e = new PDOException($e->getMessage(), $e->getCode());
                }
            }
            // Check to reconnect
            if ($tries < 10 && in_array($e->getMessage(), $lostConnectionMessages)) {
                $retry = true;
                $tries++;
            } else {
                throw $e;
            }
        }
    } while ($retry);

    return $result;
}

2 个答案:

答案 0 :(得分:2)

我会说,是的,他们也应该检查一下。在Magento2 they removed even the lost-connection reconnect中,但在MysqlI适配器中它仍然存在。

答案 1 :(得分:2)

这取决于(总是一个好的答案:)

我认为丢失的连接应被视为系统设置中的错误。 Varien_Db_Adapter_Pdo_Mysql解决它的方式隐藏了查询时间慢的原因。我宁愿看到真正的例外,然后让Magento尝试自动重新建立连接。

锁定等待超时也是如此。我想知道这种超时是否发生。通过自动重试屏蔽它们可能会使错误“消失”,但不会解决实际问题。

此类自动恢复代码至少应该可以通过系统配置中的某个选项进行配置,例如“启用数据库查询恢复模式”或类似的选项,默认为“禁用”。