做可用的软件!!!多次事务,缩小事务单位。

/**
 * 超过过期时间未拼团成功的全部报废,并退款
 */
public function clearUnSuccessOrder() {
    $group_order = M('group_order');
    $capture_group_order = $group_order
        ->where(['is_pay'=>1,'status'=>1,'expired_time'=>['lt',time()]])
        ->select();

    // todo改造,成功一条,commit一条
    $error_msg_arr = [];
    $success_count = 0;
    $fail_count = 0;
    if ($capture_group_order) {
        $group_purchase = M('group_purchase');
        $group_reward   = M('group_reward');
        vendor('Func.WxPay');
        foreach ($capture_group_order as $k=>$v) {
            M()->startTrans();
            // step1 修改订单状态
            $edit_data = [
                'status' => -2,
                'updatetime' => time()
            ];
            $edit_group_order_flag = $group_order
                ->where(['id'=>$v['id']])
                ->save($edit_data);
            if ($edit_group_order_flag === false) {
                M()->rollback();
                $error_msg_arr[] = date('Y-m-d H:i:s').'-清理过期时间未拼团成功订单:修改状态不成功';
                $fail_count++;
                continue;
            }

            // step2 撤回已占用库存
            $group_flag = $group_purchase->where(['id'=>$v['group_id']])->setDec('buyed_stock');
            if ($group_flag === false) {
                M()->rollback();
                $error_msg_arr[] = date('Y-m-d H:i:s').'-清理未支付订单:修改库存失败';
                $fail_count++;
                continue;
            }

            // step3 撤回已占用惊喜金额
            if ((int)$v['reward_id'] > 0) {
                $reward_edit_data  = [
                    'status' => 1
                ];
                $group_reward_flag = $group_reward->where(['id' => $v['reward_id']])->save($reward_edit_data);
                if ($group_reward_flag === false) {
                    M()->rollback();
                    $error_msg_arr[] = date('Y-m-d H:i:s').'-清理未支付订单:修改惊喜失败';
                    $fail_count++;
                    continue;
                }
            }
            // step4 退回付款金额
            $refund_result = WxPay::refundOrder($v['billno'], $v['payed_price'], $v['payed_price']);
            if ((int)$refund_result['num'] === 1) {
                $refund_order_edit_data = [
                    'refund_transaction_id' => $refund_result['refund_id'],
                    'refund_order_sn'       => $refund_result['refund_no'],
                    'is_refund'             => 1,
                ];
                $refund_order_edit_flag = $group_order->where(['id' => $v['id']])->save($refund_order_edit_data);
                if ($refund_order_edit_flag === false) { // 如果失败,再改一次
                    $refund_order_edit_data = [
                        'is_refund'             => 1,
                    ];
                    $group_order->where(['id' => $v['id']])->save($refund_order_edit_data);
//                        M()->rollback();
//                        $error_msg_arr[] = date('Y-m-d H:i:s').'-清理未支付订单:修改退款失败'.$refund_result['desc'];
//                        $fail_count++;
//                        continue;
                }
            } else {
                M()->rollback();
                $error_msg_arr[] = date('Y-m-d H:i:s').'-清理未支付订单:退款失败'.$refund_result['desc'];
                $fail_count++;
                continue;
            }
            M()->commit();
            $success_count++;
        }

    }
    $error_msg_arr[] = date('Y-m-d H:i').'-清理过期时间未拼团成功订单:本次共清理'.count($capture_group_order).'个拼团失败订单'.',成功了'.$success_count.',失败了'.$fail_count.'个'.PHP_EOL;
    exit(var_export($error_msg_arr,true).PHP_EOL);
}

一次循环,一个事务。
确保大部分整体事务能够提交上去。
并记录下,成功的数量,失败的数量。以及具体的原因。

posted @ 2019-05-29 14:25  TBHacker  阅读(174)  评论(0编辑  收藏  举报