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 Protege 中的Entities下面的界面删除了如何复原
  • ¥15 scrapy爬虫求帮
  • ¥15 imageEnView绘图问题
  • ¥15 关于#python#的问题:您好可以加您一下联系方式吗,在复现的时候确实有点问题难以解决
  • ¥15 联想电脑重装系统时无法发现硬盘
  • ¥15 MATLAB与UR10e实体机械臂建立通讯
  • ¥15 c++题需要快一点不用opencv
  • ¥15 关于#java#的问题:想要咨询Flowable流程引擎框架的问题
  • ¥15 vscode里面怎么用plaformio强调串口啊
  • ¥20 针对计算后数据做一致性检验可以用Bland Altman法吗