Php 服务器延迟时Mysql记录丢失
客户使用创建订单的应用程序交付货物。在数据库中,它将生成Php 服务器延迟时Mysql记录丢失,php,mysql,laravel,server,Php,Mysql,Laravel,Server,客户使用创建订单的应用程序交付货物。在数据库中,它将生成order\u delivery表 然后生成记录货物库存变化的goods\u stock\u vary\u history表 它们在一笔交易中 order\u delivery有一个goods\u stock\u vary\u history 但有一天,当服务器延迟时,客户创建了订单。然后他存在应用程序并再次创建订单 过了一会儿,他说他看不见他的订单 我发现goods\u stock\u vary\u history的记录,其字段orde
order\u delivery
表
然后生成记录货物库存变化的goods\u stock\u vary\u history
表
它们在一笔交易中
order\u delivery
有一个goods\u stock\u vary\u history
但有一天,当服务器延迟时,客户创建了订单。然后他存在应用程序并再次创建订单 过了一会儿,他说他看不见他的订单 我发现
goods\u stock\u vary\u history
的记录,其字段order\u delivery\u id
的值为2
所以我试图找到主键为2的order\u delivery
。
我找不到它。有主键1、3等,主键为自动递增
order\u delivery
仅软删除;没有人能删除那条记录
本项目使用Laravel5.1和如下代码:
DB::beginTransaction();
foreach($order\u goods\u矩阵为$order\u id=>$goods\u矩阵){
$goods\u amount=OrderServices::countgoods颜色矩阵($goods\u矩阵);
如果($goods\u amount==0){
DB::rollback();
Redis::del($user\u id.'u good\u delever');
返回$this->fail(self::ERROR_代码,“传递失败,计数不能为零”);
}
如果(intval($order_id)>0&&$goods_amount>0){
$goods\u matrix=json\u encode($goods\u matrix,true);
//创建订单交付
$ret=OrderServices::createDelivery($exist\U flag、$user\U id、$store\U id、$order\U id、$GOODES\U matrix、OrderDelivery::DELIVERY\U TYPE\U COMMON、$created\U at);
如果($ret['code']<0){
DB::rollback();
Redis::del($user\u id.'u good\u delever');
返回$this->fail(self::ERROR_代码,“交付失败”。$ret['msg']);
}
$get_history_id_arr[]=$ret['get_stock_history']['goods_stock_vary_history_id'];
}
}
$store\u goods\u sku=GoodsServiceV3::getGoodsSku($store\u id);
foreach($get\u history\u id\u arr as$get\u history\u id\u info){
$get_history_detail[]=goodsstockservice v2::getgoodsstockvary history detail($store_id,$get_history_id_info);
}
DB::commit();
在函数createDelivery
中:
$order_delivery=array();
$order\u delivery['order\u id']=$order\u id;
$order_delivery['customer_id']=$order_base[“买方_用户_id”];
$order\u delivery['delivery\u goods\u color\u size\u matrix']=$delivery\u goods\u color\u size\u matrix;
$order\u delivery['delivery\u goods\u amount']=$delivery\u goods\u amount;
$order\u delivery['operate\u user\u id']=$user\u id;
$order\u delivery['delivery\u type']=$delivery\u type;
$order\U delivery['exist\U flag']=$exist\U flag;
$order\u delivery['deliver\u timestamp']=$created\u at;
$order\u delivery\u id=OrderDelivery::insertGetId($order\u delivery);
if($order\u delivery\u id==false){
返回数组('code'=>-3,'msg'=>'Deliver fail');
}
$reverse\u delivery\u goods\u color\u size\u matrix\u array=商品库存服务::reverseGoodsColorSizeMatrix($delivery\u goods\u color\u size\u matrix\u array);
//创建商品\u库存\u变化\u历史记录
$get\u stock\u History=GoodsTockService::addStockVariation($exist\u flag,$user\u id,$store\u id,$reverse\u delivery\u goods\u size\u matrix\u array,GoodsTockService::stock\u TYPE\u DELIVER,GoodsTockService::stock\u TYPE\u DELIVER\u DEFAULT\u备注,$order\u delivery\u id,null,$order\u base[“买方\用户\ id”],$created\u at);
返回数组('code'=>0,'order\u delivery\u id'=>$order\u delivery\u id,'get\u stock\u history'=>$get\u stock\u history);
我找到了原因。
我创建了一个触发器来跟踪删除后的每个订单交付
记录
然后我发现,order\u delivery
记录仍然缺失,并且跟踪表没有任何记录
因此,丢失的order\u delivery
记录不会被某人或某种方法删除
所以我认为丢失的记录不是丢失的,它只是回滚,在回滚之前插入另一个order\u delivery
,这使它看起来像丢失了一样
然后我尝试记录每个数据库操作的结果,以获取详细信息
我发现有一条线没有处理失败的操作
这些代码是两年前编写的,事务部分很臭,需要手动回滚失败操作。和返回
失败消息
更好的方法是这样的:
DB::beginTransaction();
try {
...
OrderServices::createDelivery($exist_flag, $user_id, $store_id, $order_id, $goods_matrix, OrderDelivery::DELIVERY_TYPE_COMMON, $created_at);
...
DB::commit();
} catch(\Throwable $e) {
DB::rollback();
throw $e;
}
更改后,丢失记录现象不再显示。我找到了原因。
我创建了一个触发器来跟踪删除后的每个订单交付
记录
然后我发现,order\u delivery
记录仍然缺失,并且跟踪表没有任何记录
因此,丢失的order\u delivery
记录不会被某人或某种方法删除
所以我认为丢失的记录不是丢失的,它只是回滚,在回滚之前插入另一个order\u delivery
,这使它看起来像丢失了一样
然后我尝试记录每个数据库操作的结果,以获取详细信息
我发现有一条线没有处理失败的操作
这些代码是两年前编写的,事务部分很臭,需要手动回滚失败操作。和返回
失败消息
更好的方法是这样的:
DB::beginTransaction();
try {
...
OrderServices::createDelivery($exist_flag, $user_id, $store_id, $order_id, $goods_matrix, OrderDelivery::DELIVERY_TYPE_COMMON, $created_at);
...
DB::commit();
} catch(\Throwable $e) {
DB::rollback();
throw $e;
}
更改后,丢失记录的现象不再显示