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.

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

报告相同问题?

悬赏问题

  • ¥20 R语言单细胞测序 对seurat对象进行标准化时出现问题
  • ¥15 Anaconda navigator updateor一直更新
  • ¥15 请问如何在matlab里使用raven工具?
  • ¥100 关于ios手游充值到一定金额,再点充值提示公众号的问题。
  • ¥15 求一个stm32串口控制程序
  • ¥20 Windows 驱动开发版本疑问相关
  • ¥15 MAC 未能打开磁盘映像
  • ¥15 fastcap使用,二维导体输入问题
  • ¥15 hosts修改后不能访问
  • ¥15 关于化学反应速率C++编译问题/FLUENT