内部讨论.md 6.2 KB

[TOC]

1. 为什么要翻新

1.1. 代码可维护性

mes的代码,采用的java拼装sql,然后sql非常复杂,大量无效流程分支的情况

例如下面:一个看似简单的查询

    public CoreReturnObject doQueryData(ArrayList<String> list,String[] arr,String strPlanSql,String bathYear)
    {
        String sql = CoreXmlSqlParsersFactory.getSql("FrmReportOutput.doQueryData").replace("#COLUMNS#", list.get(0));
        sql +=CoreConverter.toSqlConditionString("t.STORAGE_NO", arr);
        sql = sql.replace("#CONDITIONS#", list.get(1));
        sql = sql + list.get(2);
        sql += " )F1)F";
        sql += " LEFT JOIN (SELECT SUM(NVL(T1.CUT_WEIGHT,'0')*NVL(T1.REAL_INDOUBLE_NUM,'0')) CUT_WEIGHT,#JUDGE_STOVE_NO1# T1.HEAT_PLAN_NO,T1.PRO_PLAN_ID,T1.GX_PLAN_NO FROM PLN_ZY_ZG_C T1,MIL_PLAN S1 WHERE T1.HEAT_PLAN_NO = S1.ID AND S1.BACK_PLAN_FLAG = '0'" +
                " AND S1.BACK_SLAB_FLAG = '0'  AND T1.CUT_TARGET = '返废' #BATH_YEAR# GROUP BY #JUDGE_STOVE_NO1# T1.HEAT_PLAN_NO,T1.PRO_PLAN_ID,T1.GX_PLAN_NO) D ON F.PRO_PLAN_ID_ZG = D.PRO_PLAN_ID AND F.GX_PLAN_NO_ZG = D.GX_PLAN_NO #DD# ";
        sql += " AND F.OUTSTOCK_TYPE_CODE = '800801' AND F.RK =1";
        if(!strPlanSql.equals(""))
        {
            sql = sql.replace("#DD#", strPlanSql).replace("#JUDGE_STOVE_NO#", "JUDGE_STOVE_NO,").replace("#JUDGE_STOVE_NO1#", "T1.JUDGE_STOVE_NO,");
        }else
        {
            sql = sql.replace("#DD#", "").replace("#JUDGE_STOVE_NO#", "").replace("#JUDGE_STOVE_NO1#", "");
        }
        if(!bathYear.equals(""))
        {
            sql = sql.replace("#BATH_YEAR#", " AND S1.BAL_YEAR_MONTH = '"+bathYear+"'");
        }else
        {
            sql = sql.replace("#BATH_YEAR#", "");
        }
        return this.getData(sql);
    }

存在以下问题

  1. 参数全装list请求里。

  2. 部分sql由前端告知(存在严重的注入风险)

  3. 前端后端采用信任方式(不验证身份)

  4. 在xml里面另外又维护了大段sql,任何一个修改需要 从3个地方结合sql才能知道在干嘛

  5. #号占位符,风险极高

  6. 很随意就星星分组查询

例如下面:一个看似简单的查询对应的sql.xml部分

select 
#columns#,
DECODE(T1.IS_DEALER, '0', '自用', '1', '双经销', '2', '来料加工','3','定销订购') IS_DEALER,
       DECODE(T1.BACK_FLAG, '0', '正常坯', '1', '回炉坯','2','套尺坯') BACK_FLAG,
       MAX(S1.PLAN_TIME_B) PLAN_TIME_B,
       T2.LOCATION_NAME,
       T2.LARY_NO,
       T2.STORAGE_NO,
       (SELECT T3.STORAGE_NAME
          FROM YDM_BS_STORAGE T3
         WHERE T3.STORAGE_NO = T2.STORAGE_NO) STORAGE_NAME,
       T1.PRODUCT_FLAG,
       T1.MAT_STATUS,
       T1.STOVE_NO,
       T1.JUDGE_STOVE_NO,
       T1.JUDGE_STOVE_NO_LG,
       T1.SOURE_NAME,
       T1.MATERIAL_NAME,
       T1.GRADENAME,
       S1.ORDER_NO || '/' || S1.ORDER_SEQ AS ORDER_NO,
       T1.DIMATER,
       T1.ACT_LEN,
       T1.FIX_NUM,
       T1.FIX_LEN,
       DECODE(T1.QCM_STAUS, '00', '合格', '11', '待处理', '22', '废品') QCM_STAUS,
       T1.PLINE_NAME,
       T1.BELONG_NAME,
       MAX(TO_CHAR(T1.INSTOCK_TIME, 'YYYY-MM-DD HH24:MI:SS')) INSTOCK_TIME,
       T1.MEMO,
       T1.MEMO MEMO2,
       (SELECT T2.BASENAME
          FROM COM_BASE_INFO T2
         WHERE T2.BASECODE = T1.JUDGE_RESULT_CODE) JUDGE_RESULT_CODE,
       MAX((SELECT S1.PLINE_NAME
             FROM PLN_ORDER_ZG_S S1
            WHERE S1.PRO_PLAN_ID = T1.PRO_PLAN_ID_ZG
              AND S1.GX_PLAN_NO = T1.GX_PLAN_NO_ZG)) PLINE_NAME_NEXT,
       sum(T1.ACT_COUNT) as ACT_COUNT,
       sum(T1.ACT_WEIGHT) as ACT_WEIGHT,
        T1.MNG_LOCK_FLAG
  FROM MAT_GP_M T1
  LEFT JOIN YDM_GP_BUTTRESS T2
    on T1.MAT_NO = T2.MAT_NO
  LEFT JOIN YDM_BS_STORAGE S
    ON S.STORAGE_NO = T2.STORAGE_NO
  LEFT JOIN PLN_ORDER_ZG_S S1
    ON T1.PRO_PLAN_ID_ZG = S1.PRO_PLAN_ID
   AND T1.GX_PLAN_NO_ZG = S1.GX_PLAN_NO
 WHERE T1.MAT_NO = T2.MAT_NO
    AND T1.IS_SETFOOT = '0'
  #something#
 group by T1.IS_DEALER,
          T1.BACK_FLAG,
          T2.LOCATION_NAME,
          T2.LARY_NO,
          T2.STORAGE_NO,
          T1.PRODUCT_FLAG,
          T1.MAT_STATUS,
          T1.STOVE_NO,
          T1.JUDGE_STOVE_NO,
          T1.JUDGE_STOVE_NO_LG,
          T1.SOURE_NAME,
          T1.MATERIAL_NAME,
          T1.GRADENAME,
          S1.ORDER_NO,
          S1.ORDER_SEQ,
          T1.DIMATER,
          T1.ACT_LEN,
          T1.FIX_NUM,
          T1.FIX_LEN,
          T1.QCM_STAUS,
          T1.PLINE_NAME,
          T1.BELONG_NAME,
          T1.MEMO,
          T1.JUDGE_RESULT_CODE,
          T1.MNG_LOCK_FLAG

存在以下问题

  1. 字段随意转码 (正确做法是在java中转换,索引之敌)

  2. 随意的子查询 (在开发中是大忌)

  3. 随意的分组查询(分组查询不允许用在业务模块上)

  4. 多张表查询,应该尽量采用主表查询,从表拼装,多次查询的方式,这里为了省事一锅炖。

  5. 存在大量魔法占位符 #column#,#something# 之类,难以理解 (带来了天量的维护困难)

1.2. 并发及带来的相关灾难

1.2.1 概念

    事务

        一件事情,不管多少步骤,要么做完,要么不做,不允许出现中间状态

例如:

小明给小方银行转账。步骤如下: 1、小明,账上扣掉1块

2、小明流水上增加一条支出信息

3、小方,账上增加1块

4、小方流水上增加一条收入信息

    

    如果不带事务,那么中间状态不能是每方都能接受的

所以,我们在实际工作中带上事务

1、先冻结小明那条数据(其他人不能写或者读(不包括脏读))

2、小明zhangs

2、流水表写入2条可回退事务插入

3、冻结小方的那条数据(其他人不能读或者写)

    事务死锁

  1. 暴力解锁

  2. 并发

  3. 串行

  4. 并发及带来的相关灾难

  5. 项目健壮的重要性

  6. 翻新发现问题并带来可靠维护文档

  7. 可扩展开发性

  8. 翻新步骤

  9. 怎么保证翻新是可靠的,而不是带来新问题翻新步骤

  10. 施工进度怎么控制

  11. 旧系统下线的时机

  12. 甲方操作人员需要配合做什么

  13. 旧系统产生的历史错误数据如何处理

  14. 告警中台推销