以前官網作了一次改版,運行一年多的時間,狀態良好。在性能和抗壓程度上都有了比較大的提高。php
然而,在對接了 TMS(第三方配送系統)
和電子發票以後,會常常發生訂單狀態異常的狀況。html
通過老大和慧哥的分析(我參與了問題的解決,未參與分析),流程以下:sql
TMS
操做訂單完成(完成中);TMS
更新完成,訂單狀態發生改變;TMS
更新以前的狀態。正常的 Phalcon
的 update
流程以下:性能
$robot = Robots::findFirstById($id);
$robot->name = 'wali';
$robot->update();
// ------- or -------
$robot = Robots::findFirstById($id);
$robot->update(['name' => 'wali']);
複製代碼
理想中的 SQL
語句:this
UPDATE `robots` SET `name` = 'wali' WHERE `id` = 1
複製代碼
現實中的 SQL
語句:spa
UPDATE `robots` SET `name` = 'wali', `model` => '1' WHERE `id` = 1
複製代碼
也就是說 Phalcon
會將取到的全部數據都更新一次。code
若是在A取到結果以後,B也操做並更新了這個記錄以後,A再更新,那麼B的操做就至關於沒有作,這就形成了上面的尷尬一幕。htm
解決方案有好幾個,我會從最不建議的方式開始。blog
Phalcon
更新一條記錄的過程當中,會調用 model
類中的 save
方法,而 save
方法提供了一個參數 whiteList
,在 whiteList
以內的字段是不會被更新的。get
優勢: 能夠限制某些字段的更新。
缺點: 針對當前狀況,須要在每一處操做限制,並且須要更改 update
的方式爲 save
,工做量太大。
能夠獲取寫服務以後,直接 execute
SQL
語句,這樣能夠避免全部字段更新的狀況。
優勢: 適合批量更新或者多表更新的狀況。
缺點: 和第一種方案同樣,須要修改每一處地方,工做量大。
Phalcon
自己仍是提供了只更新變化字段的方法的,調用也很簡單,在 Model
初始化時,調用 useDynamicUpdate
方法,參數爲 true
。
public function initialize() {
$this->useDynamicUpdate(true); // 就是它,神奇的方法
$this->setReadConnectionService('slave');
$this->setWriteConnectionService('master');
$this->setSource($this->_tableName);
}
複製代碼
優勢: 便捷,快速,改動地方少。
缺點: 固然是有的,不過我沒有想到...
有些雷,會在不知不覺中埋下,因此對於未知的東西,仍是要多瞭解,纔可以做出更加正確的決定。
-- EOF --
本文轉載自IMJCW
原文連接:Phalcon只更新改變的字段