dragon8837 2019-02-21 19: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 06: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.

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

报告相同问题?

悬赏问题

  • ¥30 给出MySQL数据库workbench代码
  • ¥15 文本挖掘法衡量保险公司数字化转型
  • ¥15 Direct2D,一个图像如何绘制到不同窗体?
  • ¥15 putimage函数输出了不属于指定路径的图片
  • ¥15 ros2运行代码出现问题
  • ¥15 关于#c++#的问题,请各位专家解答!
  • ¥15 Linux系统虚拟机连不上网络
  • ¥15 Qt控件QCombobox样式设计之后箭头不见了
  • ¥15 8阶光立方求驱动层和应用层代码(原理图已给出)
  • ¥15 如何在不联网的时候使用下面导入的库
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部