• 【上线复盘】20190329-一个刷新数据的接口是如何导致几十万的订单数据错误


    一、业务场景

      本次上线的功能主要是对工单结算进行优化,支持用户使用多张卡,多张优惠券,多张兑换码进行支付。由于之前只支持单张卡,单张优惠券,单张兑换码。所以涉及订单表和订单详情表的表结构修改,新增一些字段,比如记录多张卡的支付数据等。

    如订单主表:

    -- 订单相关
    -- coupon_pay_data [{"couponId":1,"couponFee":1}]
    ALTER TABLE saas_order_record ADD COLUMN `coupon_pay_data` json  DEFAULT NULL COMMENT '优惠券抵扣支付数据';
    -- card_pay_data [{"cardId":1,"cardType":1,"amount":1,"num":1,"giftNum":1}] cardType 1次卡 2储值卡,
    ALTER TABLE saas_order_record ADD COLUMN `card_pay_data` json  DEFAULT NULL COMMENT '会员卡抵扣支付数据';
    -- redemption_pay_data [{"redemptionCode":"1","redemptionFee":1}]
    ALTER TABLE saas_order_record ADD COLUMN `redemption_pay_data` json  DEFAULT NULL COMMENT '兑换码抵扣支付数据';

      那么针对历史数据,需要维护这些字段。由于无法通过sql直接维护,所有我的同事通过Java代码提供一个接口来耍数据,只要逻辑清楚,实现起来不太难。

    二、如何导致数据错误的呢?

    1)我们直接看代码:

        @Override
        @Transactional
        public ApiResponse sync(String orderId) {
            //1. 筛选所有订单数据
            Instant time1 = Instant.now();
            List<SaasOrderRecord> saasOrderRecords = getOrderRecords(orderId);
            if (CollectionUtils.isNotEmpty(saasOrderRecords)) {
                saasOrderRecords.parallelStream().forEach(
                        x -> {
                            List<SaasServiceOrderInfo> saasServiceOrderInfos = getOrderServicesByOrderId(x.getId());
                            List<OrderGoods> orderGoods = getOrderGoodsByOrderId(x.getId());
            。。。
            。。。        
        //2.3 redemption_pay_data
        String redemptionPayData = getRedemptionPayData(saasServiceOrderInfos);
        x.setRedemptionPayData(redemptionPayData);
        //2. 更新saas_order_record
        saasOrderRecordDAO.updateByPrimaryKeySelective(x);

    从上面的1、2来看,没啥问题。第一步查询出订单,然后set想复制的字段,再更新。

    2)我们再看看

            List<SaasOrderRecord> saasOrderRecords = getOrderRecords(orderId);方法实现

     @Override
        public List<SaasOrderRecord> getOrderRecords(String orderId) {
            if (StringUtils.isNotBlank(orderId)) {
                return saasOrderRecordDAO.findOrders(" and id=" + orderId);
            }
            return saasOrderRecordDAO.findOrders("");
        }
    @Select(" select id,coupon_id AS couponId,coupon_fee2 AS couponFee2,card_id AS cardId  from saas_order_record where 1=1 and (coupon_id != 0 OR card_id !=0) ${condition}")
        List<SaasOrderRecord> findOrders(@Param("condition") String condition);

    我们从sql来看,会发现只查询了部分字段。查询部分字段是推荐的做法,减少了查询数据量,提高处理效率。但是用的全量类SaasOrderRecord,从更新的方法saasOrderRecordDAO.updateByPrimaryKeySelective(x);来看也没什么问题,因为updateByPrimaryKeySelective方法只更新字段值不为null的字段。

    3)真正的问题就出现在,不想更新的字段值不为null

      那么我们就会想,sql中没查询的字段不就是null么。那为啥就不为null了呢?

    问题就在于SaasOrderRecord类,我们一看这个类就知道了:

    package com.xinchan.xcauto.orm.mysql.merchants.domain.entity;
    
    import java.io.Serializable;
    import java.math.BigDecimal;
    import java.util.Date;
    
    /**
     * saas_order_record
     * @author 
     */
    public class SaasOrderRecord implements Serializable {
        /**
         * 自增id
         */
        private Long id;
    
        /**
         * 创建时间
         */
        private Date createdAt = new Date();
    
        /**
         * 更新时间
         */
        private Date updatedAt = new Date();
    
        /**
         * 状态
         */
        private Integer status;
    
        /**
         * 用户id
         */
        private Long uid;
    
        /**
         * 门店id
         */
        private Integer storeId;
    
        /**
         * 销售人id
         */
        private Long sellerId;
    
        /**
         * 操作人id
         */
        private Long operatorId;
    
        /**
         * 会员卡id
         */
        private Long cardId;
    
        /**
         * 手机
         */
        private String phone;
    
        /**
         * 车牌号
         */
        private String carNum;
    
        /**
         * 订单号
         */
        private String tradeNo;
    
        /**
         * 订单类型
         */
        private Integer orderType;
    
        /**
         * 发起方式
         */
        private Integer initType;
    
        /**
         * 付款时间
         */
        private Date payTime;
    
        /**
         * 过期时间
         */
        private Long expireIn;
    
        /**
         * 支付方式
         */
        private Integer payType;
    
        /**
         * 原总价
         */
        private Long totalFee = 0L;
    
        /**
         * 实际总价
         */
        private Long actualFee = 0L;
    
        /**
         * 抵扣金额
         */
        private Long couponFee = 0L;
    
        /**
         * 赠送金额
         */
        private Long giftFee = 0L;
    
        /**
         * 原余额
         */
        private Long originalBalance = 0L;
    
        /**
         * 备注
         */
        private String note;
    
        /**
         * 微信openid
         */
        private String wxOpenId;
    
        /**
         * 优惠券id
         */
        private Long couponId;
    
        /**
         * 优惠券抵扣金额
         */
        private Long couponFee2 = 0L;
    
        /**
         * 人为指定的优惠金额
         */
        private Long couponFee3 = 0L;
    
        /**
         * 订单来源
         */
        private Integer src;
    
        /**
         * 结算状态
         */
        private Integer settleStatus;
    
        /**
         * 提现状态
         */
        private Integer withdrawStatus;
    
        /**
         * 提现记录id
         */
        private Long withdrawRecordId;
    
        /**
         * 结算id
         */
        private Long settleRecordId;
    
        /**
         * 工单id
         */
        private Long worksheetId;
    
        /**
         * 手续费
         */
        private Long cost;
    
        /**
         * 费率
         */
        private BigDecimal rate;
    
        /**
         * 使用的卡id列表
         */
        private String useCards;
    
        /**
         * 是否扣卡短信通知 0 否 1 是
         */
        private Boolean ifDeductCardShortNote;
    
        /**
         * 门店赠送项原价
         */
        private Long storeCouponFee;
    
        /**
         * 是否使用他人会员卡 0 否 1 是
         */
        private Boolean useOthersCard;
    
        /**
         * 是否他人代付 0 否 1 是 2未知
         */
        private Integer othersPay;
    
        /**
         * 工单编号
         */
        private String worksheetNo;
    
        /**
         * 提现金额
         */
        private Long withdrawFee;
    
        /**
         * 使用兑换码抵扣原价
         */
        private Integer redemptionFee;
    
        /**
         * 组合支付数据
         */
        private String groupPayData = "[]";
    
        /**
         * 优惠券抵扣支付数据
         */
        private String couponPayData = "[]";
    
        /**
         * 会员卡抵扣支付数据
         */
        private String cardPayData = "[]";
    
        /**
         * 兑换码抵扣支付数据
         */
        private String redemptionPayData = "[]";
    
        private static final long serialVersionUID = 1L;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public Date getCreatedAt() {
            return createdAt;
        }
    
        public void setCreatedAt(Date createdAt) {
            this.createdAt = createdAt;
        }
    
        public Date getUpdatedAt() {
            return updatedAt;
        }
    
        public void setUpdatedAt(Date updatedAt) {
            this.updatedAt = updatedAt;
        }
    
        public Integer getStatus() {
            return status;
        }
    
        public void setStatus(Integer status) {
            this.status = status;
        }
    
        public Long getUid() {
            return uid;
        }
    
        public void setUid(Long uid) {
            this.uid = uid;
        }
    
        public Integer getStoreId() {
            return storeId;
        }
    
        public void setStoreId(Integer storeId) {
            this.storeId = storeId;
        }
    
        public Long getSellerId() {
            return sellerId;
        }
    
        public void setSellerId(Long sellerId) {
            this.sellerId = sellerId;
        }
    
        public Long getOperatorId() {
            return operatorId;
        }
    
        public void setOperatorId(Long operatorId) {
            this.operatorId = operatorId;
        }
    
        public Long getCardId() {
            return cardId;
        }
    
        public void setCardId(Long cardId) {
            this.cardId = cardId;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public String getCarNum() {
            return carNum;
        }
    
        public void setCarNum(String carNum) {
            this.carNum = carNum;
        }
    
        public String getTradeNo() {
            return tradeNo;
        }
    
        public void setTradeNo(String tradeNo) {
            this.tradeNo = tradeNo;
        }
    
        public Integer getOrderType() {
            return orderType;
        }
    
        public void setOrderType(Integer orderType) {
            this.orderType = orderType;
        }
    
        public Integer getInitType() {
            return initType;
        }
    
        public void setInitType(Integer initType) {
            this.initType = initType;
        }
    
        public Date getPayTime() {
            return payTime;
        }
    
        public void setPayTime(Date payTime) {
            this.payTime = payTime;
        }
    
        public Long getExpireIn() {
            return expireIn;
        }
    
        public void setExpireIn(Long expireIn) {
            this.expireIn = expireIn;
        }
    
        public Integer getPayType() {
            return payType;
        }
    
        public void setPayType(Integer payType) {
            this.payType = payType;
        }
    
        public Long getTotalFee() {
            return totalFee;
        }
    
        public void setTotalFee(Long totalFee) {
            this.totalFee = totalFee;
        }
    
        public Long getActualFee() {
            return actualFee;
        }
    
        public void setActualFee(Long actualFee) {
            this.actualFee = actualFee;
        }
    
        public Long getCouponFee() {
            return couponFee;
        }
    
        public void setCouponFee(Long couponFee) {
            this.couponFee = couponFee;
        }
    
        public Long getGiftFee() {
            return giftFee;
        }
    
        public void setGiftFee(Long giftFee) {
            this.giftFee = giftFee;
        }
    
        public Long getOriginalBalance() {
            return originalBalance;
        }
    
        public void setOriginalBalance(Long originalBalance) {
            this.originalBalance = originalBalance;
        }
    
        public String getNote() {
            return note;
        }
    
        public void setNote(String note) {
            this.note = note;
        }
    
        public String getWxOpenId() {
            return wxOpenId;
        }
    
        public void setWxOpenId(String wxOpenId) {
            this.wxOpenId = wxOpenId;
        }
    
        public Long getCouponId() {
            return couponId;
        }
    
        public void setCouponId(Long couponId) {
            this.couponId = couponId;
        }
    
        public Long getCouponFee2() {
            return couponFee2;
        }
    
        public void setCouponFee2(Long couponFee2) {
            this.couponFee2 = couponFee2;
        }
    
        public Long getCouponFee3() {
            return couponFee3;
        }
    
        public void setCouponFee3(Long couponFee3) {
            this.couponFee3 = couponFee3;
        }
    
        public Integer getSrc() {
            return src;
        }
    
        public void setSrc(Integer src) {
            this.src = src;
        }
    
        public Integer getSettleStatus() {
            return settleStatus;
        }
    
        public void setSettleStatus(Integer settleStatus) {
            this.settleStatus = settleStatus;
        }
    
        public Integer getWithdrawStatus() {
            return withdrawStatus;
        }
    
        public void setWithdrawStatus(Integer withdrawStatus) {
            this.withdrawStatus = withdrawStatus;
        }
    
        public Long getWithdrawRecordId() {
            return withdrawRecordId;
        }
    
        public void setWithdrawRecordId(Long withdrawRecordId) {
            this.withdrawRecordId = withdrawRecordId;
        }
    
        public Long getSettleRecordId() {
            return settleRecordId;
        }
    
        public void setSettleRecordId(Long settleRecordId) {
            this.settleRecordId = settleRecordId;
        }
    
        public Long getWorksheetId() {
            return worksheetId;
        }
    
        public void setWorksheetId(Long worksheetId) {
            this.worksheetId = worksheetId;
        }
    
        public Long getCost() {
            return cost;
        }
    
        public void setCost(Long cost) {
            this.cost = cost;
        }
    
        public BigDecimal getRate() {
            return rate;
        }
    
        public void setRate(BigDecimal rate) {
            this.rate = rate;
        }
    
        public String getUseCards() {
            return useCards;
        }
    
        public void setUseCards(String useCards) {
            this.useCards = useCards;
        }
    
        public Boolean getIfDeductCardShortNote() {
            return ifDeductCardShortNote;
        }
    
        public void setIfDeductCardShortNote(Boolean ifDeductCardShortNote) {
            this.ifDeductCardShortNote = ifDeductCardShortNote;
        }
    
        public Long getStoreCouponFee() {
            return storeCouponFee;
        }
    
        public void setStoreCouponFee(Long storeCouponFee) {
            this.storeCouponFee = storeCouponFee;
        }
    
        public Boolean getUseOthersCard() {
            return useOthersCard;
        }
    
        public void setUseOthersCard(Boolean useOthersCard) {
            this.useOthersCard = useOthersCard;
        }
    
        public Integer getOthersPay() {
            return othersPay;
        }
    
        public void setOthersPay(Integer othersPay) {
            this.othersPay = othersPay;
        }
    
        public String getWorksheetNo() {
            return worksheetNo;
        }
    
        public void setWorksheetNo(String worksheetNo) {
            this.worksheetNo = worksheetNo;
        }
    
        public Long getWithdrawFee() {
            return withdrawFee;
        }
    
        public void setWithdrawFee(Long withdrawFee) {
            this.withdrawFee = withdrawFee;
        }
    
        public Integer getRedemptionFee() {
            return redemptionFee;
        }
    
        public void setRedemptionFee(Integer redemptionFee) {
            this.redemptionFee = redemptionFee;
        }
    
        public String getGroupPayData() {
            return groupPayData;
        }
    
        public void setGroupPayData(String groupPayData) {
            this.groupPayData = groupPayData;
        }
    
        public String getCouponPayData() {
            return couponPayData;
        }
    
        public void setCouponPayData(String couponPayData) {
            this.couponPayData = couponPayData;
        }
    
        public String getCardPayData() {
            return cardPayData;
        }
    
        public void setCardPayData(String cardPayData) {
            this.cardPayData = cardPayData;
        }
    
        public String getRedemptionPayData() {
            return redemptionPayData;
        }
    
        public void setRedemptionPayData(String redemptionPayData) {
            this.redemptionPayData = redemptionPayData;
        }
    
        @Override
        public boolean equals(Object that) {
            if (this == that) {
                return true;
            }
            if (that == null) {
                return false;
            }
            if (getClass() != that.getClass()) {
                return false;
            }
            SaasOrderRecord other = (SaasOrderRecord) that;
            return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
                && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
                && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
                && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus()))
                && (this.getUid() == null ? other.getUid() == null : this.getUid().equals(other.getUid()))
                && (this.getStoreId() == null ? other.getStoreId() == null : this.getStoreId().equals(other.getStoreId()))
                && (this.getSellerId() == null ? other.getSellerId() == null : this.getSellerId().equals(other.getSellerId()))
                && (this.getOperatorId() == null ? other.getOperatorId() == null : this.getOperatorId().equals(other.getOperatorId()))
                && (this.getCardId() == null ? other.getCardId() == null : this.getCardId().equals(other.getCardId()))
                && (this.getPhone() == null ? other.getPhone() == null : this.getPhone().equals(other.getPhone()))
                && (this.getCarNum() == null ? other.getCarNum() == null : this.getCarNum().equals(other.getCarNum()))
                && (this.getTradeNo() == null ? other.getTradeNo() == null : this.getTradeNo().equals(other.getTradeNo()))
                && (this.getOrderType() == null ? other.getOrderType() == null : this.getOrderType().equals(other.getOrderType()))
                && (this.getInitType() == null ? other.getInitType() == null : this.getInitType().equals(other.getInitType()))
                && (this.getPayTime() == null ? other.getPayTime() == null : this.getPayTime().equals(other.getPayTime()))
                && (this.getExpireIn() == null ? other.getExpireIn() == null : this.getExpireIn().equals(other.getExpireIn()))
                && (this.getPayType() == null ? other.getPayType() == null : this.getPayType().equals(other.getPayType()))
                && (this.getTotalFee() == null ? other.getTotalFee() == null : this.getTotalFee().equals(other.getTotalFee()))
                && (this.getActualFee() == null ? other.getActualFee() == null : this.getActualFee().equals(other.getActualFee()))
                && (this.getCouponFee() == null ? other.getCouponFee() == null : this.getCouponFee().equals(other.getCouponFee()))
                && (this.getGiftFee() == null ? other.getGiftFee() == null : this.getGiftFee().equals(other.getGiftFee()))
                && (this.getOriginalBalance() == null ? other.getOriginalBalance() == null : this.getOriginalBalance().equals(other.getOriginalBalance()))
                && (this.getNote() == null ? other.getNote() == null : this.getNote().equals(other.getNote()))
                && (this.getWxOpenId() == null ? other.getWxOpenId() == null : this.getWxOpenId().equals(other.getWxOpenId()))
                && (this.getCouponId() == null ? other.getCouponId() == null : this.getCouponId().equals(other.getCouponId()))
                && (this.getCouponFee2() == null ? other.getCouponFee2() == null : this.getCouponFee2().equals(other.getCouponFee2()))
                && (this.getCouponFee3() == null ? other.getCouponFee3() == null : this.getCouponFee3().equals(other.getCouponFee3()))
                && (this.getSrc() == null ? other.getSrc() == null : this.getSrc().equals(other.getSrc()))
                && (this.getSettleStatus() == null ? other.getSettleStatus() == null : this.getSettleStatus().equals(other.getSettleStatus()))
                && (this.getWithdrawStatus() == null ? other.getWithdrawStatus() == null : this.getWithdrawStatus().equals(other.getWithdrawStatus()))
                && (this.getWithdrawRecordId() == null ? other.getWithdrawRecordId() == null : this.getWithdrawRecordId().equals(other.getWithdrawRecordId()))
                && (this.getSettleRecordId() == null ? other.getSettleRecordId() == null : this.getSettleRecordId().equals(other.getSettleRecordId()))
                && (this.getWorksheetId() == null ? other.getWorksheetId() == null : this.getWorksheetId().equals(other.getWorksheetId()))
                && (this.getCost() == null ? other.getCost() == null : this.getCost().equals(other.getCost()))
                && (this.getRate() == null ? other.getRate() == null : this.getRate().equals(other.getRate()))
                && (this.getUseCards() == null ? other.getUseCards() == null : this.getUseCards().equals(other.getUseCards()))
                && (this.getIfDeductCardShortNote() == null ? other.getIfDeductCardShortNote() == null : this.getIfDeductCardShortNote().equals(other.getIfDeductCardShortNote()))
                && (this.getStoreCouponFee() == null ? other.getStoreCouponFee() == null : this.getStoreCouponFee().equals(other.getStoreCouponFee()))
                && (this.getUseOthersCard() == null ? other.getUseOthersCard() == null : this.getUseOthersCard().equals(other.getUseOthersCard()))
                && (this.getOthersPay() == null ? other.getOthersPay() == null : this.getOthersPay().equals(other.getOthersPay()))
                && (this.getWorksheetNo() == null ? other.getWorksheetNo() == null : this.getWorksheetNo().equals(other.getWorksheetNo()))
                && (this.getWithdrawFee() == null ? other.getWithdrawFee() == null : this.getWithdrawFee().equals(other.getWithdrawFee()))
                && (this.getRedemptionFee() == null ? other.getRedemptionFee() == null : this.getRedemptionFee().equals(other.getRedemptionFee()))
                && (this.getGroupPayData() == null ? other.getGroupPayData() == null : this.getGroupPayData().equals(other.getGroupPayData()))
                && (this.getCouponPayData() == null ? other.getCouponPayData() == null : this.getCouponPayData().equals(other.getCouponPayData()))
                && (this.getCardPayData() == null ? other.getCardPayData() == null : this.getCardPayData().equals(other.getCardPayData()))
                && (this.getRedemptionPayData() == null ? other.getRedemptionPayData() == null : this.getRedemptionPayData().equals(other.getRedemptionPayData()));
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
            result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
            result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
            result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode());
            result = prime * result + ((getUid() == null) ? 0 : getUid().hashCode());
            result = prime * result + ((getStoreId() == null) ? 0 : getStoreId().hashCode());
            result = prime * result + ((getSellerId() == null) ? 0 : getSellerId().hashCode());
            result = prime * result + ((getOperatorId() == null) ? 0 : getOperatorId().hashCode());
            result = prime * result + ((getCardId() == null) ? 0 : getCardId().hashCode());
            result = prime * result + ((getPhone() == null) ? 0 : getPhone().hashCode());
            result = prime * result + ((getCarNum() == null) ? 0 : getCarNum().hashCode());
            result = prime * result + ((getTradeNo() == null) ? 0 : getTradeNo().hashCode());
            result = prime * result + ((getOrderType() == null) ? 0 : getOrderType().hashCode());
            result = prime * result + ((getInitType() == null) ? 0 : getInitType().hashCode());
            result = prime * result + ((getPayTime() == null) ? 0 : getPayTime().hashCode());
            result = prime * result + ((getExpireIn() == null) ? 0 : getExpireIn().hashCode());
            result = prime * result + ((getPayType() == null) ? 0 : getPayType().hashCode());
            result = prime * result + ((getTotalFee() == null) ? 0 : getTotalFee().hashCode());
            result = prime * result + ((getActualFee() == null) ? 0 : getActualFee().hashCode());
            result = prime * result + ((getCouponFee() == null) ? 0 : getCouponFee().hashCode());
            result = prime * result + ((getGiftFee() == null) ? 0 : getGiftFee().hashCode());
            result = prime * result + ((getOriginalBalance() == null) ? 0 : getOriginalBalance().hashCode());
            result = prime * result + ((getNote() == null) ? 0 : getNote().hashCode());
            result = prime * result + ((getWxOpenId() == null) ? 0 : getWxOpenId().hashCode());
            result = prime * result + ((getCouponId() == null) ? 0 : getCouponId().hashCode());
            result = prime * result + ((getCouponFee2() == null) ? 0 : getCouponFee2().hashCode());
            result = prime * result + ((getCouponFee3() == null) ? 0 : getCouponFee3().hashCode());
            result = prime * result + ((getSrc() == null) ? 0 : getSrc().hashCode());
            result = prime * result + ((getSettleStatus() == null) ? 0 : getSettleStatus().hashCode());
            result = prime * result + ((getWithdrawStatus() == null) ? 0 : getWithdrawStatus().hashCode());
            result = prime * result + ((getWithdrawRecordId() == null) ? 0 : getWithdrawRecordId().hashCode());
            result = prime * result + ((getSettleRecordId() == null) ? 0 : getSettleRecordId().hashCode());
            result = prime * result + ((getWorksheetId() == null) ? 0 : getWorksheetId().hashCode());
            result = prime * result + ((getCost() == null) ? 0 : getCost().hashCode());
            result = prime * result + ((getRate() == null) ? 0 : getRate().hashCode());
            result = prime * result + ((getUseCards() == null) ? 0 : getUseCards().hashCode());
            result = prime * result + ((getIfDeductCardShortNote() == null) ? 0 : getIfDeductCardShortNote().hashCode());
            result = prime * result + ((getStoreCouponFee() == null) ? 0 : getStoreCouponFee().hashCode());
            result = prime * result + ((getUseOthersCard() == null) ? 0 : getUseOthersCard().hashCode());
            result = prime * result + ((getOthersPay() == null) ? 0 : getOthersPay().hashCode());
            result = prime * result + ((getWorksheetNo() == null) ? 0 : getWorksheetNo().hashCode());
            result = prime * result + ((getWithdrawFee() == null) ? 0 : getWithdrawFee().hashCode());
            result = prime * result + ((getRedemptionFee() == null) ? 0 : getRedemptionFee().hashCode());
            result = prime * result + ((getGroupPayData() == null) ? 0 : getGroupPayData().hashCode());
            result = prime * result + ((getCouponPayData() == null) ? 0 : getCouponPayData().hashCode());
            result = prime * result + ((getCardPayData() == null) ? 0 : getCardPayData().hashCode());
            result = prime * result + ((getRedemptionPayData() == null) ? 0 : getRedemptionPayData().hashCode());
            return result;
        }
    
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append(getClass().getSimpleName());
            sb.append(" [");
            sb.append("Hash = ").append(hashCode());
            sb.append(", id=").append(id);
            sb.append(", createdAt=").append(createdAt);
            sb.append(", updatedAt=").append(updatedAt);
            sb.append(", status=").append(status);
            sb.append(", uid=").append(uid);
            sb.append(", storeId=").append(storeId);
            sb.append(", sellerId=").append(sellerId);
            sb.append(", operatorId=").append(operatorId);
            sb.append(", cardId=").append(cardId);
            sb.append(", phone=").append(phone);
            sb.append(", carNum=").append(carNum);
            sb.append(", tradeNo=").append(tradeNo);
            sb.append(", orderType=").append(orderType);
            sb.append(", initType=").append(initType);
            sb.append(", payTime=").append(payTime);
            sb.append(", expireIn=").append(expireIn);
            sb.append(", payType=").append(payType);
            sb.append(", totalFee=").append(totalFee);
            sb.append(", actualFee=").append(actualFee);
            sb.append(", couponFee=").append(couponFee);
            sb.append(", giftFee=").append(giftFee);
            sb.append(", originalBalance=").append(originalBalance);
            sb.append(", note=").append(note);
            sb.append(", wxOpenId=").append(wxOpenId);
            sb.append(", couponId=").append(couponId);
            sb.append(", couponFee2=").append(couponFee2);
            sb.append(", couponFee3=").append(couponFee3);
            sb.append(", src=").append(src);
            sb.append(", settleStatus=").append(settleStatus);
            sb.append(", withdrawStatus=").append(withdrawStatus);
            sb.append(", withdrawRecordId=").append(withdrawRecordId);
            sb.append(", settleRecordId=").append(settleRecordId);
            sb.append(", worksheetId=").append(worksheetId);
            sb.append(", cost=").append(cost);
            sb.append(", rate=").append(rate);
            sb.append(", useCards=").append(useCards);
            sb.append(", ifDeductCardShortNote=").append(ifDeductCardShortNote);
            sb.append(", storeCouponFee=").append(storeCouponFee);
            sb.append(", useOthersCard=").append(useOthersCard);
            sb.append(", othersPay=").append(othersPay);
            sb.append(", worksheetNo=").append(worksheetNo);
            sb.append(", withdrawFee=").append(withdrawFee);
            sb.append(", redemptionFee=").append(redemptionFee);
            sb.append(", groupPayData=").append(groupPayData);
            sb.append(", couponPayData=").append(couponPayData);
            sb.append(", cardPayData=").append(cardPayData);
            sb.append(", redemptionPayData=").append(redemptionPayData);
            sb.append(", serialVersionUID=").append(serialVersionUID);
            sb.append("]");
            return sb.toString();
        }
    }
    View Code

    好多字段给了默认值。所以就为导致这次给默认值的字段都被更新为默认值了

     /**
         * 创建时间
         */
        private Date createdAt = new Date();
    
        /**
         * 更新时间
         */
        private Date updatedAt = new Date();
     /**
         * 原总价
         */
        private Long totalFee = 0L;
    
        /**
         * 实际总价
         */
        private Long actualFee = 0L;
    
        /**
         * 抵扣金额
         */
        private Long couponFee = 0L;
    
        /**
         * 赠送金额
         */
        private Long giftFee = 0L;
    
        /**
         * 原余额
         */
        private Long originalBalance = 0L;
     /**
         * 优惠券抵扣金额
         */
        private Long couponFee2 = 0L;
    
        /**
         * 人为指定的优惠金额
         */
        private Long couponFee3 = 0L;
     /**
         * 组合支付数据
         */
        private String groupPayData = "[]";
    
        /**
         * 优惠券抵扣支付数据
         */
        private String couponPayData = "[]";
    
        /**
         * 会员卡抵扣支付数据
         */
        private String cardPayData = "[]";
    
        /**
         * 兑换码抵扣支付数据
         */
        private String redemptionPayData = "[]";

    三、针对问题的处理方案

    1.因为只影响了SaasOrderRecord这一张表,并且创建时间也被new Date()刷新成当前时间,那么我们可以很容易的通过创建时间不同这个条件来修复数据。

    所有让运维将上线前备份库中这张表取个其他表名导入到线上库中,通过sql直接修复。

    update saas_order_record s, saas_order_record_2019_03_29 c
    set s.created_at = c.created_at,
    s.updated_at = c.updated_at,
    s.total_fee=c.total_fee, 
    s.actual_fee=c.actual_fee,
    s.coupon_fee=c.coupon_fee,
    s.gift_fee=c.gift_fee,
    s.original_balance=c.original_balance,
    s.coupon_fee2=c.coupon_fee2,
    s.coupon_fee3=c.coupon_fee3,
    s.group_pay_data=c.group_pay_data
     where s.id=c.id and s.created_at<>c.created_at;

    2.将SaasOrderRecord类中的默认值去掉,防止代码中还有类似的代码而出错

    3.将刷数据的接口关闭

  • 相关阅读:
    [MySQL]You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
    mysql的索引
    Mysql中的Btree与Hash索引
    Tomcat集群的session共享
    Linux常用命令总结
    docker elk
    docker+mysql+zabix-server环境搭建
    centos7系统服务管理
    Linux vim常用命令
    linux系统日志查看
  • 原文地址:https://www.cnblogs.com/756623607-zhang/p/10629740.html
Copyright © 2020-2023  润新知