6

2 つの Magento アダプター クラスVarien_Db_Adapter_MysqliVarien_Db_Adapter_Pdo_Mysqlを比較すると、メソッドraw_queryのクエリ例外処理にいくつかの違いがあることがわかります。

<?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 の equal メソッドと比較すると、別のエラー処理が見つかります。タイムアウトではなく、失われた接続をチェックします。

<?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;
}
4

2 に答える 2

2

はい、これもチェックする必要があります。Magento2では、接続が失われた再接続も削除されましたが、MysqlIアダプターではまだ存在しています。

于 2012-07-06T16:56:36.537 に答える
2

それは異なります(常に良い答えです:)

接続が失われた場合は、システム セットアップのバグと見なされるべきだと思います。それを回避する方法Varien_Db_Adapter_Pdo_Mysqlは、遅いクエリ時間の原因を隠します。実際の例外を確認してから、Magento に接続を自動的に再確立してもらいたいと思います。

ロック待ちタイムアウトについても同様です。そのようなタイムアウトが発生するかどうかを知りたいです。自動再試行でそれらをマスクすると、エラーが「なくなる」可能性がありますが、実際の問題は修正されません。

このような自動回復コードは、少なくともシステム構成のいくつかのオプションを介して構成可能である必要があります。たとえば、「DBクエリ回復モードを有効にする」などで、デフォルトで「無効」に設定されています。

于 2012-07-09T09:55:48.243 に答える