服务器滞后时Mysql记录丢失

时间:2019-02-22 03:06:32

标签: php mysql laravel server

客户使用创建订单交付商品的应用程序。在数据库中,它将生成order_delivery表;

然后生成goods_stock_vary_history表,该表记录了商品库存的变化;

他们正在进行一笔交易。

order_delivery有一个goods_stock_vary_history


但是有一天,客户在服务器延迟时创建了订单。然后他存在该应用程序并再次创建订单。

过了一会儿,他说他看不到他的命令。

我发现goods_stock_vary_history的记录,并且其字段order_delivery_id的值为2;

所以我尝试找到order_delivery主键是2。 我找不到它。有主键1和3等。主键是自动递增;

order_delivery仅具有软删除功能;没有人可以删除该记录。


该项目使用Laravel5.1和如下代码:

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();

在功能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 个答案:

答案 0 :(得分:0)

我找到了原因。 我创建了一个触发器来跟踪删除后的每个order_delivery条记录。

然后我发现order_delivery记录仍然丢失,并且跟踪表中没有任何记录。

因此,丢失的order_delivery记录不会被某人或某些方法删除。

因此,我认为丢失的记录不会丢失,只是回滚,而在回滚之前插入了另一个order_delivery,就像丢失了一样。

然后我尝试记录每个数据库操作结果以获取详细信息。

我发现有一条线无法处理失败操作。

这些代码是两年前编写的,事务部分很臭,您需要手动回滚失败操作。和return失败消息。

更好的方法是这样的:

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

更改后,丢失的记录现象不再显示。