2 つの Magento アダプター クラスVarien_Db_Adapter_MysqliとVarien_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;
}