dragon8837 2019-02-22 03:06
浏览 39
已采纳

服务器滞后时Mysql记录丢失

Customer use the app which create the order to deliver goods. In the database, it will generate the order_delivery table;

And then generate the goods_stock_vary_history table that record the changes of goods stock;

They are in one transaction.

The order_delivery has one goods_stock_vary_history.


But one day the customer created the order when server lag. And then he exist the app and create order again.

After a while, he say he cannot see his order.

I found the record of goods_stock_vary_history and its field order_delivery_id has value 2;

So I try to find order_delivery that primary key is 2. And I cannot find it. There have primary keys 1 and 3 etc. The primary key is auto increment;

order_delivery has soft delete only; Nobody can delete that record.


The project use Laravel5.1 and the codes like below:

DB::beginTransaction();
foreach ($order_goods_matrix as $order_id => $goods_matrix) {
            $goods_amount = OrderServices::countGoodsColorSizeMatrixAmount($goods_matrix);
            if($goods_amount==0){
                DB::rollback();
                Redis::del($user_id . '_good_delever');
                return $this->fail(self::ERROR_CODE, "Deliver Fail. The count cannot be zero");
            }
            if (intval($order_id) > 0 && $goods_amount > 0) {
                $goods_matrix = json_encode($goods_matrix, true);
                // Create order delivery
                $ret = OrderServices::createDelivery($exist_flag, $user_id, $store_id, $order_id, $goods_matrix, OrderDelivery::DELIVERY_TYPE_COMMON, $created_at);
                if ($ret['code'] < 0) {
                    DB::rollback();
                    Redis::del($user_id . '_good_delever');

                    return $this->fail(self::ERROR_CODE, "Deliver Fail" . $ret['msg']);
                }
                $get_history_id_arr[] = $ret['get_stock_histtory']['goods_stock_vary_history_id'];
            }
        }
        $store_goods_sku = GoodsServiceV3::getGoodsSku($store_id);
        foreach ($get_history_id_arr as $get_history_id_info) {
            $get_history_detail[] = GoodsStockServiceV2::getGoodsStockVaryHistoryDetail($store_id, $get_history_id_info);
        }
        DB::commit();

in the function createDelivery:

$order_delivery = array();
        $order_delivery['order_id'] = $order_id;
        $order_delivery['customer_id'] = $order_base["buyer_user_id"];
        $order_delivery['delivery_goods_color_size_matrix'] = $delivery_goods_color_size_matrix;
        $order_delivery['delivery_goods_amount'] = $delivery_goods_amount;
        $order_delivery['operate_user_id'] = $user_id;
        $order_delivery['delivery_type'] = $delivery_type;
        $order_delivery['exist_flag'] = $exist_flag;
        $order_delivery['deliver_timestamp'] = $created_at;


        $order_delivery_id = OrderDelivery::insertGetId($order_delivery);
        if ($order_delivery_id == false) {
            return array('code' => -3, 'msg' => 'Deliver fail');
        }
          $reverse_delivery_goods_color_size_matrix_array = GoodsStockServices::reverseGoodsColorSizeMatrix($delivery_goods_color_size_matrix_array);

        // create goods_stock_vary_history
        $get_stock_histtory = GoodsStockServices::addStockVariation($exist_flag, $user_id, $store_id, $reverse_delivery_goods_color_size_matrix_array, GoodsStockServices::STOCK_TYPE_DELIVER, GoodsStockServices::STOCK_TYPE_DELIVER_DEFAULT_REMARK, $order_delivery_id, null, $order_base["buyer_user_id"], $created_at);
        return array('code' => 0, 'order_delivery_id' => $order_delivery_id, 'get_stock_histtory' => $get_stock_histtory);
  • 写回答

1条回答 默认 最新

  • douye4254 2019-03-25 14:02
    关注

    I found the reason. I created a trigger to track each order_delivery records after be deleted.

    And then I found that order_delivery record is still missing, and the track table doesn't have any records.

    So the missing order_delivery record is not deleted by someone or some method.

    So I think the missing record is not missing, it just rollback, and another order_delivery inserted before it rollback, that make it like missing.

    And then I try to log every database operation result for getting details.

    I found there is a line not deal with the fail operation.

    These code is written two years ago, the transaction part is smelly, you need to manually rollback the fail operation. and return fail message.

    The better way is like this:

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

    After I change it, the missing record phenomenon not showing again.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程