前言
之前官網(wǎng)做了一次改版,運行一年多的時間掸掸,狀態(tài)良好忽洛。在性能和抗壓程度上都有了比較大的提升。
然而袁稽,在對接了 TMS(第三方配送系統(tǒng))
和電子發(fā)票之后,會經(jīng)常發(fā)生訂單狀態(tài)異常的情況擒抛。
問題
經(jīng)過老大和慧哥的分析(我參與了問題的解決推汽,未參與分析)补疑,流程如下:
- 配送員在
TMS
操作訂單完成(完成中); - 開電子發(fā)票的腳本獲取了訂單的信息歹撒;
-
TMS
更新完成莲组,訂單狀態(tài)發(fā)生改變; - 開電子發(fā)票的腳本重新更新了訂單的信息暖夭,訂單被變更為
TMS
更新之前的狀態(tài)锹杈。
正常的 Phalcon
的 update
流程如下:
$robot = Robots::findFirstById($id);
$robot->name = 'wali';
$robot->update();
// ------- or -------
$robot = Robots::findFirstById($id);
$robot->update(['name' => 'wali']);
理想中的 SQL
語句:
UPDATE `robots` SET `name` = 'wali' WHERE `id` = 1
現(xiàn)實中的 SQL
語句:
UPDATE `robots` SET `name` = 'wali', `model` => '1' WHERE `id` = 1
也就是說 Phalcon
會將取到的所有數(shù)據(jù)都更新一次。
如果在A取到結(jié)果之后迈着,B也操作并更新了這個記錄之后竭望,A再更新,那么B的操作就相當于沒有做裕菠,這就造成了上面的尷尬一幕咬清。
解決
解決方案有好幾個,我會從最不建議的方式開始奴潘。
使用白名單
Phalcon
更新一條記錄的過程中枫振,會調(diào)用 model
類中的 save
方法,而 save
方法提供了一個參數(shù) whiteList
萤彩,在 whiteList
之內(nèi)的字段是不會被更新的粪滤。
優(yōu)點: 可以限制某些字段的更新。
缺點: 針對當前情況雀扶,需要在每一處操作限制杖小,而且需要更改 update
的方式為 save
,工作量太大愚墓。
自己寫SQL
可以獲取寫服務之后予权,直接 execute
SQL
語句,這樣可以避免所有字段更新的情況浪册。
優(yōu)點: 適合批量更新或者多表更新的情況扫腺。
缺點: 和第一種方案一樣,需要修改每一處地方村象,工作量大笆环。
設置只更新變化的字段
Phalcon
本身還是提供了只更新變化字段的方法的,調(diào)用也很簡單厚者,在 Model
初始化時躁劣,調(diào)用 useDynamicUpdate
方法,參數(shù)為 true
库菲。
public function initialize()
{
$this->useDynamicUpdate(true); // 就是它账忘,神奇的方法
$this->setReadConnectionService('slave');
$this->setWriteConnectionService('master');
$this->setSource($this->_tableName);
}
優(yōu)點: 便捷,快速,改動地方少鳖擒。
缺點: 當然是有的溉浙,不過我沒有想到...
總結(jié)
有些雷,會在不知不覺中埋下蒋荚,所以對于未知的東西放航,還是要多了解,才能夠作出更加正確的決定圆裕。
-- EOF --
本文轉(zhuǎn)載自IMJCW
原文鏈接:Phalcon只更新改變的字段