Phalcon只更新改变的字段

文章讨论了在Phalcon框架中遇到的订单状态异常问题,并详细分析了原因。提出了三种解决方案:使用白名单、自己写SQL及设置只更新变化的字段,并对比了它们的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

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

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

问题

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

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

正常的 Phalconupdate 流程如下:

$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);
}

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

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

总结

有些雷,会在不知不觉中埋下,所以对于未知的东西,还是要多了解,才能够作出更加正确的决定。

– EOF –
本文转载自IMJCW
原文链接:Phalcon只更新改变的字段

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值