Phalcon只更新改变的字段

2018-02-03 10:38:44来源:https://juejin.im/post/5a7181b46fb9a01c95266677作者:稀土掘金人点击

分享

之前官网做了一次改版,运行一年多的时间,状态良好。在性能和抗压程度上都有了比较大的提升。



然而,在对接了TMS(第三方配送系统)
和电子发票之后,会经常发生订单状态异常的情况。


问题

经过老大和慧哥的分析(我参与了问题的解决,未参与分析),流程如下:


配送员在TMS
操作订单完成(完成中);
开电子发票的脚本获取了订单的信息;
TMS
更新完成,订单状态发生改变;
开电子发票的脚本重新更新了订单的信息,订单被变更为TMS
更新之前的状态。


正常的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


现实中的SQL
语句:


UPDATE `robots` SET `name` = 'wali', `model` => '1' WHERE `id` = 1


也就是说Phalcon
会将取到的所有数据都更新一次。


如果在A取到结果之后,B也操作并更新了这个记录之后,A再更新,那么B的操作就相当于没有做,这就造成了上面的尴尬一幕。


解决

解决方案有好几个,我会从最不建议的方式开始。


使用白名单


Phalcon
更新一条记录的过程中,会调用model
类中的save
方法,而save
方法提供了一个参数whiteList
,在whiteList
之内的字段是不会被更新的。



优点:可以限制某些字段的更新。



缺点:针对当前情况,需要在每一处操作限制,而且需要更改update
的方式为save
,工作量太大。


自己写SQL


可以获取写服务之后,直接execute
SQL
语句,这样可以避免所有字段更新的情况。



优点:适合批量更新或者多表更新的情况。



缺点:和第一种方案一样,需要修改每一处地方,工作量大。


设置只更新变化的字段


Phalcon
本身还是提供了只更新变化字段的方法的,调用也很简单,在Model
初始化时,调用useDynamicUpdate
方法,参数为true


public function initialize()
{
$this->useDynamicUpdate(true); // 就是它,神奇的方法
$this->setReadConnectionService('slave');
$this->setWriteConnectionService('master');
$this->setSource($this->_tableName);
}


优点:便捷,快速,改动地方少。



缺点:当然是有的,不过我没有想到...


最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台