摘要:當使用訪問數(shù)據(jù)庫且腳本需要長時間執(zhí)行時,頻繁會遇見的錯誤。分析問題產(chǎn)生原因因為腳本較長時間未與數(shù)據(jù)庫進行通信,導(dǎo)致數(shù)據(jù)庫連接超時與服務(wù)器斷開連接導(dǎo)致,這時使用斷開的數(shù)據(jù)庫連接操作數(shù)據(jù)庫,就會產(chǎn)生的錯誤提示。
當PHP 使用PDO訪問數(shù)據(jù)庫且腳本需要長時間執(zhí)行時,頻繁會遇見’ MySQL server has gone away’的錯誤。分析問題產(chǎn)生原因:因為腳本較長時間未與數(shù)據(jù)庫進行通信,導(dǎo)致數(shù)據(jù)庫連接超時與服務(wù)器斷開連接導(dǎo)致,這時使用斷開的數(shù)據(jù)庫連接操作數(shù)據(jù)庫(CRUD),就會產(chǎn)生’ MySQLserver has gone away’的錯誤提示。解決之道在于長時間運行的腳本需要與服務(wù)器保持心跳,一旦檢測到連接斷開,則需要重新連接數(shù)據(jù)庫。
在考慮保持最小數(shù)據(jù)庫負載(檢測手段開銷小,心跳頻率不能太過頻繁)和較高腳本健壯性(需要更高頻率的心跳),可以選擇不同的心跳測試策略和心跳頻率。以下的代碼給出了一個解決辦法,通過單件封裝了數(shù)據(jù)庫連接,當每次獲取數(shù)據(jù)庫連接時會判斷是否需要檢測連接仍然有效,如果連接失效則重建連接,在腳本健壯性與服務(wù)器壓力之間保持一個最好的平衡點
/*
使用單件來維護數(shù)據(jù)庫連接,當需要數(shù)據(jù)連接時需要從單件獲取,這樣在單件內(nèi)部可以檢測并恢復(fù)數(shù)據(jù)連接
*/
class DBConnection
{
const RECHECK_FREQUENCY = 300;// 5 minutes private static $instance = null; private $dbh = NULL; private $lastCheckTime = 0; private function __construct() { $this->lastCheckTime =time(); } public static function instance() { if (NULL ==self ::$instance) { self:: $instance =newDBConnection(); } return self::$instance; } public function dbh() { $this->ensureConnection2(); return $this->dbh; } private function ensureConnection() { if (is_null($this->dbh)) return $this->makeConnection(); try { $status = $this->dbh->getAttribute(PDO::ATTR_SERVER_INFO); error_log("MySQL server checked been there"); } catch(PDOException$e) { if((int)$e->errorInfo[1]== 2006 &&$e->errorInfo[2] == "MySQLserver has gone away") { error_log("MySQLserver has gone away, try to reconnection..."); return $this->makeConnection(); } error_log("Get db server attribute failed: " .$e->getMessage()); } return $this->dbh; } private function ensureConnection2() { if (is_null($this->dbh)) return $this->makeConnection(); try { $now = time(); if ($now -$this->lastCheckTime> self::RECHECK_FREQUENCY) { $this->lastCheckTime =$now; $status = $this->dbh->query("select1"); error_log("MySQL server checked been there"); } } catch(PDOException$e) { if((int)$e->errorInfo[1]== 2006 &&$e->errorInfo[2] == "MySQLserver has gone away") { error_log("MySQL server has gone away, try to reconnection..."); return $this->makeConnection(); } error_log("Get db server attribute failed: " .$e->getMessage()); } return $this->dbh; } private function makeConnection() { try { $options = array ( PDO:: MYSQL_ATTR_INIT_COMMAND => "set names "utf8"", PDO:: ATTR_PERSISTENT => false, PDO:: ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ); $this->dbh = new PDO(DB_DSN, DB_USER, DB_PASSWORD, $options); return $this->dbh; } catch (PDOException$e) { error_log("Connection failed: " .$e->getMessage()); exit(); } return null; }
}
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/26106.html
摘要:直接在上執(zhí)行語句,報錯搜索得知當客戶端或服務(wù)器收到大于字節(jié)的信息包時,將發(fā)出信息包過大錯誤,并關(guān)閉連接。對于某些客戶端,如果通信信息包過大,在執(zhí)行查詢期間,可能會遇到丟失與服務(wù)器的連接錯誤。 接手了同事的項目,其中有一個功能是保存郵件模板(包含圖片),同事之前的做法是把圖片進行base64編碼然后存在mysql數(shù)據(jù)庫中(字段類型為mediumtext)然后保存三張圖片(大概400k)的...
閱讀 1638·2019-08-30 15:54
閱讀 2387·2019-08-30 15:52
閱讀 2076·2019-08-29 15:33
閱讀 3050·2019-08-28 17:56
閱讀 3248·2019-08-26 13:54
閱讀 1684·2019-08-26 12:16
閱讀 2458·2019-08-26 11:51
閱讀 1656·2019-08-26 10:26