如果我比较两个 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;
}