我有一個奇怪的bug,這裏涉及到mysql和php。我想知道它是否也是我們服務器的性能問題。快速插入導致數據丟失
我有一個班級用於管理回扣促銷代碼。代碼非常好,工作正常,而且完全沒有它應該做的。 saveChanges()操作根據對象的狀態發送INSERT或UPDATE,並且在當前上下文中將只插入原因,我試圖生成優惠券代碼。
該類的saveChanges是這樣的:(我知道,我不應該使用舊的mysql,但由於軟件的架構限制,我沒有選擇,所以請不要抱怨那部分)
public function saveChanges($asNew = false){
//Get the connection
global $conn_panier;
//Check if the rebate still exists
if($this->isNew() || $asNew){
//Check unicity if new
if(reset(mysql_fetch_assoc(mysql_query('SELECT COUNT(*) FROM panier_rabais_codes WHERE code_coupon = "'.mysql_real_escape_string($this->getCouponCode(), $conn_panier).'"', $conn_panier))) > 0){
throw new Activis_Catalog_Models_Exceptions_ValidationException('Coupon code "'.$this->getCouponCode().'" already exists in the system', $this, __METHOD__, $this->getCouponCode());
}
//Update the existing rebate
mysql_query($q = 'INSERT INTO panier_rabais_codes
(
`no_rabais`,
`code_coupon`,
`utilisation`,
`date_verrou`
)VALUES(
'.$this->getRebate()->getId().',
"'.mysql_real_escape_string(stripslashes($this->getCouponCode()), $conn_panier).'",
'.$this->getCodeUsage().',
"'.($this->getInvalidityDate() === NULL ? '0000-00-00 00:00:00' : date('Y-m-d G:i:s', strtotime($this->getInvalidityDate()))).'"
)', $conn_panier);
return (mysql_affected_rows($conn_panier) >= 1);
}else{
//Update the existing rebate
mysql_query('UPDATE panier_rabais_codes
SET
`utilisation` = '.$this->getCodeUsage().',
`date_verrou` = "'.($this->getInvalidityDate() === NULL ? '0000-00-00 00:00:00' : date('Y-m-d G:i:s', strtotime($this->getInvalidityDate()))).'"
WHERE
no_rabais = '.$this->getRebate()->getId().' AND code_coupon = "'.mysql_real_escape_string($this->getCouponCode(), $conn_panier).'"', $conn_panier);
return (mysql_affected_rows($conn_panier) >= 0);
}
}
因此,您可以看到,代碼本身非常簡單且乾淨,如果插入成功則返回true,否則返回false。
while($codes_to_generate > 0){
//Sleep to delay mysql choking on the input
usleep(100);
//Generate a random code
$code = strtoupper('RC'.$rebate->getId().rand(254852, 975124));
$code .= strtoupper(substr(md5($code), 0, 1));
$rebateCode = new Activis_Catalog_Models_RebateCode($rebate);
$rebateCode->setCouponCode($code);
$rebateCode->setCodeUsage($_REQUEST['utilisation_generer']);
try{
if($rebateCode->saveChanges()){
$codes_to_generate--;
$generated_codes[] = $code;
}
}catch(Exception $ex){
}
}
正如你可以在這裏看到,有兩兩件事需要注意:
代碼的其他部分採用隨機算法,在是這樣產生的代碼。如果我從saveChanges返回true,那麼生成的代碼數和生成的代碼數組纔會被填充,所以mysql必須報告爲此部分發生的信息插入。
另一個珍聞是同時的第一行:
//Sleep to delay mysql choking on the input
usleep(100);
跆拳道?那麼這篇文章就是關於這個的。我的代碼完美地工作與少量的代碼生成。但是,如果我要求mysql一次保存超過幾個代碼,我必須使用usleep或mysql刪除這些行中的一部分。它會報告存在受影響的行但不保存它們。
在100行以下,我不需要調節,然後我需要根據要插入的行數量進行睡眠。它一定是簡單的東西,但我不知道是什麼。這裏是我試圖插入線和最小usleep油門的總和我不得不實現:
- < 100行:無
- < 300線:2毫秒
- < 1000行:5毫秒
- < 2000行:10毫秒
- < 5000行:20毫秒
- <萬線:100毫秒
謝謝您的時間
您在查詢後沒有捕獲錯誤。這不是爲了弄清楚發生了什麼而採取的第一步嗎? –
對不起,我已經這樣做了,沒有錯誤 –
因此,您實際使用的代碼與您發佈的代碼有所不同嗎?真正的代碼在每次查詢後檢查錯誤?爲什麼不張貼代碼然後 –