thinkphp5 mysql无法插入数据库且不报错 # 背景 使用thinkphp5,事务插入order订单表一条数据,无法插入数据库,但是程序不报错,查看表的自增ID有增长,说明数据库有执行插入行为,但是立马被回滚了。百思不得其解。 ```php //数据返回成功 { "result": "y", "data": { "code": "10180907165420101" } } ``` # 排查 首先更换save方法为insert,create方法,均不对。 那只可能是数据库问题,排查其他表,正常,唯独写入order订单表异常。 排查是否是表字段缓存,删除runtime文件夹,不对。 排查是否是数据库引擎或mysql设置,查阅后无此设置。 排查表名(理论上order表会被加上前缀组装成表名cc_order),但是还是把order改为orders。 实验证明更改后就正常了。 真是奇葩,我其他的项目都用的order表名,唯独这个项目不行。 难道是thinkphp的版本?其他项目都是v5.0.13 唯独这个项目升级为v5.0.20。 降级后发现还是不行。 # 解决方案(打假了,这根本行不通) 既然找到解决方案,那就简单了。 - **方案1:更改cc_order表名为cc_orders。老项目表名不好改,只能放弃。** - **方案2:指定模型的名称** ```php //把模型Order.php更改Orders.php class Orders extends Model { protected $table = "cc_order"; } ``` 更改后,数据库正常插入数据。 # 真*解决方案 上周看起来解决了,这周一来上班,同事调用接口发现又无法插入数据了。这下真懵逼了。 逐行删代码,最后终于发现错误所在了。泪流 原来我在定义订单类时,前置了一个钩子,用来让超时订单失效以及同步给其他商家订单的 ```php public function _initialize() { parent::_initialize(); Hook::add('action_begin', 'app\\weapp\\behavior\\CronRun'); } ``` 这个钩子里也使用了事务, ```php public function actionBegin(&$params) { //检查订单是否超时,超过一天未支付需要释放库存 Db::startTrans(); try { $Order = model('Order'); $OrderDetails = model('OrderDetails'); $Order->where('status', 1)->where('created_at', '<', Carbon::now()->subMinutes(30))->update(array('status' => -1, 'jst_upload_flag' => 2)); $Order->where('status', 3)->where('created_at', '<', Carbon::now()->subDays(7))->update(array('status' => 4, 'done_time' => time(), 'jst_upload_flag' => 2)); //同步数据给聚水潭 $list = $Order->where('jst_upload_flag', 2)->select(); $jst = new Jst(); foreach ($list as $key => $val) { if (in_array($val['status'], array(2, 4))) { $reback = $jst->uploadOrderToJst($val['code']); } elseif ($val['status'] == -1) { $reback = $jst->uploadCancelOrderToJst($val['code']); } if ($reback['result'] != 'y') { Log::error("订单同步聚水潭失败" . $val['code']); return false; } } Db::commit(); } catch (\Exception $e) { Db::rollback(); } } ``` 结果在同步时报错了,直接就吊事后面代码回滚了。 更改钩子为相应标签后执行 ```php Hook::add('response_end', 'app\\weapp\\behavior\\CronRun'); ``` 这下应该真正解决了