由于公司后端项目近期改造升级,之前的laravel5.6版本升级为laravel5.8版本。升级后,系统出现了很多SQL执行错误。不过老版本的系统运行的还不错,所以才有了今天的坑之旅。项目环境升级了老系统(linux+laravel5.6+php7.2+mysql5.7),新系统(linux+laravel5.8+php7.2+mysql5.7)只升级了laravel框架版本,并做了不升级其他相关服务是依赖的。但是,有大量的SQL执行错误。异常监控如下:分析过程导致这个服务报错是这么一段业务逻辑,下面通过一个demo来模拟。$pivot=UserRole::firstOrCreate(['user_id'=>3,'role_id'=>3,]);$this->addRoleHistory($user,$pivot->id);dd($pivot->id);这段代码在laravel5.6运行是没有问题的,但是升级到5.8版本会出现很多SQL执行错误,就像下面这样。laravel5.6:dd($pivot->id);//10002laravel5.8:dd($pivot->id);//null在5.6中保存的数据还能正常获取到ID,为什么在5.8中就不行了,于是立马查看了laravel5.8的releasenotes,发现并没有取消Pivot模型。添加了ID更改,所以我开始查看5.8源代码。..首先对比5.6和5.8的firstOrCreate函数,发现没有变化,代码逻辑执行正确。然后继续浏览model->save()函数的代码,发现通过函数insertAndSetId插入了不存在的数据并设置了主键ID,但是insertAndSetId函数是由一个成员属性控制的,比如自增.该属性的默认值为True,当该属性改变时,不会执行任何步骤。这个成员属性是否被操纵?于是立马查看了5.8的pivot模型的源码。最后发现中间表5.8的PivotClass默认设置了incrementing为false,所以数据插入成功,但是没有设置插入后的主键ID,导致其余服务崩溃。正常运行...修复方案是重新覆盖每个PivotClass中自增属性的值。类UserRole扩展Pivot{public$incrementing=true;protected$fillable=['user_id','role_id',];}修复后:laravel5.8:dd($pivot->id);//10003Afterword于是去仔细看了laravel5.7~laravel5.8的releasenotes,发现还是没有说到这个变化的原因,于是又去google了一遍,还是不行找到这个模因的原因。最终由于变更导致的问题被成功修复,同时也提醒我们在后续版本升级时仍需多注意UT覆盖率和版本兼容性变更测试。多维度保障工程质量。laravel5.7发行说明:https://laravel.com/docs/5.7/...laravel5.8发行说明:https://laravel.com/docs/5.8/...
