[英]How can I get php pdo code to keep retrying to connect if there are too many open connections?
我有一個問題,它現在才出現。 我使用的是共享 web 托管計划,該計划最多有 10 個並發數據庫連接。 web app有幾十個查詢,有的是pdo,有的是mysql_*。
加載一個頁面特別是在 5-6 個並發連接時達到峰值,這意味着至少需要 2 個用戶同時加載它才能在其中一個或兩個上吐出錯誤。
我知道這是低效的,我相信我可以減少很多,但這就是我目前的想法是將 pdo 代碼移動到 function 中,然后只傳遞一個查詢字符串和一個變量數組,然后讓它返回一個數組(部分是為了整理我的代碼)。
實際問題:
我怎樣才能讓這個 function 繼續重試直到它設法執行,並阻止調用它的腳本(以及任何可能調用該腳本的腳本)直到它設法執行並返回它的數據? 我不希望事情亂序執行,我很高興代碼在高峰時段延遲一秒左右
由於有人會要求代碼,這就是我目前所做的。 我把它放在一個單獨的文件中,所以我有一個中心位置來更改連接參數。 當我從測試服務器切換到肝臟服務器時,if 語句只是為了消除不斷更改參數的需要
$dbtype = "mysql";
$server_addr = $_SERVER['SERVER_ADDR'];
if ($server_addr == '192.168.1.10') {
$dbhost = "localhost";
} else {
$dbhost = "xxxxx.xxxxx.xxxxx.co.nz";
}
$dbname = "mydatabase";
$dbuser = "user";
$dbpass = "supersecretpassword";
我將該文件“包含”在 function 的頂部
include 'db_connection_params.php';
$pdo_conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
然后在一個連接上運行這樣的命令
$sql = "select * from tbl_sub_cargo_cap where sub_model_sk = ?";
$capq = $pdo_conn->prepare($sql);
$capq->execute(array($sk_to_load));
while ($caprow = $capq->fetch(PDO::FETCH_ASSOC)) {
//stuff
}
對於單個頁面,您不需要5-6個並發連接,每個頁面應該只使用1個連接。 我會嘗試重新構建應用程序的任何部分,導致單個頁面上出現多個連接。
但是,您應該能夠在連接失敗時捕獲PDOException( 連接管理文檔 ),然后重試多次。
一個簡單的例子,
<?php
$retries = 3;
while ($retries > 0)
{
try
{
$dbh = new PDO("mysql:host=localhost;dbname=blahblah", $user, $pass);
// Do query, etc.
$retries = 0;
}
catch (PDOException $e)
{
// Should probably check $e is a connection error, could be a query error!
echo "Something went wrong, retrying...";
$retries--;
usleep(500); // Wait 0.5s between retries.
}
}
10個並發連接很多。 它可以輕松地為10-15名在線用戶服務。 需要付出沉重的努力來消耗它們
所以你的代碼有問題。
主要原因有兩個:
前一個必須進行調查,但對於后者,它很簡單:
減少一個腳本中的連接數是唯一的方法。
如果代碼中有多個PDO類實例,則需要在每次調用時添加所需的超時處理代碼。 因此,無論如何都需要重編碼重寫。
用global $pdo;
替換這些新實例global $pdo;
代替。 它將花費相同的時間,但它將是永久的解決方案,而不是您想要的臨時補丁。
請明智。
PHP會自動關閉腳本末尾的所有連接,您不必關心手動關閉它們。
在一個腳本中只有一個連接是常見的做法。 它被世界各地的所有開發人員使用。 你可以毫無疑問地使用它。 只是使用它。
如果你有事務並想在數據庫中記錄一些東西,你有時需要在一個腳本中有 2 個連接
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.