Eloquent模型调用update返回true但数据库变更未生效如何解决
问题排查及解决方案
1. 模型$fillable批量赋值白名单未配置
- Laravel Eloquent为了防止批量赋值漏洞,默认要求在模型中声明允许批量赋值的字段。如果
$data里的字段没有提前加到CustomerInfo模型的$fillable白名单里,模型的update()操作会静默跳过这些字段,不会抛出错误,同时返回true。如果你使用查询构造器执行更新依然无效,可以排除该问题,因为查询构造器不走Eloquent的批量赋值校验规则。 - 解决方法:打开
CustomerInfo模型文件,把需要更新的字段加入$fillable数组:
// CustomerInfo.php protected $fillable = ['machine_name', '需要更新的字段1', '需要更新的字段2', ...];
如果测试场景下需要临时关闭批量赋值限制(不推荐生产环境使用),可以在模型中设置:
protected $guarded = [];
2. 数据库事务未提交
- 如果你的更新逻辑写在数据库事务里,执行完更新后没有调用
commit(),或者中间逻辑触发了rollBack(),更新操作会在请求结束后被回滚,数据库不会留存变更,但是update方法本身只要SQL执行无报错就会返回true。 - 解决方法:检查更新逻辑所在的上下文是否开启了事务,确认事务执行完后正确提交:
DB::beginTransaction(); try { $customerInfo = CustomerInfo::where('machine_name',$username)->firstOrFail(); $result = $customerInfo->update($data); // 其他业务逻辑 DB::commit(); // 必须调用才会将变更持久化到数据库 } catch (\Exception $e) { DB::rollBack(); throw $e; }
3. 查询条件或更新值不符合预期
- 两种常见情况会导致该问题:
where('machine_name',$username)匹配到的行不是你要更新的目标行- 匹配到的行本身的字段值和
$data里要更新的值完全一致,这时候SQL执行的影响行数为0,但Laravel的update方法只要SQL执行无错就返回true,不会按影响行数判断执行结果
- 解决方法:先打印执行的SQL、匹配到的原数据和更新参数,确认逻辑符合预期:
// 打印执行的SQL和绑定参数 dd(CustomerInfo::where('machine_name',$username)->toSql(), $username); // 打印匹配到的原数据和待更新的参数 $customerInfo = CustomerInfo::where('machine_name',$username)->firstOrFail(); dd($customerInfo->toArray(), $data);
4. 模型前置事件拦截了更新操作
- 如果你在
CustomerInfo模型中定义了updating、saving等更新前置事件,且事件逻辑中返回了false,会直接终止更新操作,但框架不会抛出错误,update方法依然返回true。 - 解决方法:检查模型中是否存在如下事件逻辑,确认没有异常返回false的情况:
protected static function booted() { static::updating(function ($model) { // 这里如果返回false会直接终止更新流程 // return false; }); }
内容的提问来源于stack exchange,提问作者Roshan Twanabasu
相关产品推荐
相关产品推荐

