在我的網站上,我們連接到多個數據庫,並且我們有一個數據庫處理類,它將句柄存儲在一個靜態數組中。 99.9%的時間,一切似乎工作正常,但時不時地處理失敗,沒有錯誤,並沒有結果返回。我已經能夠重新創建錯誤,然後使用以下語法重新創建連接:php PDO數據庫hande拒絕將結果返回給幾個成功調用後的查詢
$db = new PDO("dblib:host=" . DB_HOST . ";dbname=" . DB_DEFAULT, DB_USER, DB_PASS);
然後,它會正確返回結果。但是,我寧願爲所有數據庫使用相同的句柄,以保留與創建到數據庫的新連接相關的額外開銷......或者至少重新創建連接的次數最少。
有沒有辦法評估PDO對象,找出它失敗的原因,希望能夠弄清楚發生了什麼?
編輯: 我一直在進一步調查,並在發生此錯誤時對DB進行剖析。 PDO在遇到特定查詢後停止向服務器傳遞查詢。 (在這種情況下,它是一個插入查詢,用於測試記錄是否已經存在,如果不存在,則插入它)。
請不要誤解,這是一個可怕的,無法解決的問題,但我複製並粘貼(並普遍化)解決問題的方法。基本上,當沒有結果返回時,我從數據庫中選擇'foo',如果沒有結果,我重建連接並嘗試再次執行查詢。我不接受這個答案,因爲這很糟糕。但是這段代碼應該更好地說明我正在嘗試修復的問題。
/**
* Executes a line of sql with PDO.
*
* @param string $sql
* @param array $params
* @param bool
* @return array
*/
function execute($sql, $params = array(), $retry = false) {
//this call gets the database handle that is stored in a static array, so we can reuse the same connection
$db = db::getDB($this->_database);
if (get_class($db) != 'PDO') {
error('database handle wasn\'t created succesfully...');
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$query = $db->prepare($sql);
$query->execute($params);
} catch (Exception $ex) {
var_dump($ex);
return false;
}
$results = $query->fetchALL(PDO::FETCH_ASSOC);
if(($retry == false) && (!$results)){
$newResults = $this->testAndFixResultsIfDBGoneAway($sql, $params);
if($newResults != false){
$results = $newResults;
}
}
return $results;
}
function isConnected(){
$db = db::getDB($this->_database);
$query = $db->prepare("SELECT 'foo' AS test");
$query->execute();
$results = $query->fetchAll(PDO::FETCH_ASSOC);
//we aren't connected if we get no response
if($results == array()){
return false;
}
//if there is a response, return true
return true;
}
function testAndFixResultsIfDBGoneAway($sql, $params){
if($this->isConnected()){
return false;
}
//recreates the db connection in the db connection class
db::connect($this->_database);
$results = $this->execute($sql, $params, true);
return $results;
}
我發現我的連接消失了,我可以成功地重新啓動它,然後下一個查詢可能會失敗,我可以重複此過程多次,直到違規查詢都做了,那麼一切都開始工作通常,再次。
我真的很想知道查詢如何殺死我的數據庫連接,所以我可以阻止它發生,所以我不必在每次查詢都沒有結果後進行檢查。
這是使用設置屬性功能處理的,並且圍繞執行語句進行嘗試......(在我看來,它是SOP)。它在不拋出異常的情況下執行,但對於可以從SSMS中獲得結果的非常簡單的查詢,不會返回任何結果。 –
我唯一能做的其他事情就是[這個bug](https://bugs.php.net/bug.php?id=40639),似乎在8年以後仍然開放... – Sammitch
我已經增加了更多的信息,現在我發現了更多的錯誤。 –