2012年8月3日 星期五

Java - 如何透過jco 與 TimerTask 做自動資料同步

前提 :

  1. 自己的資料庫準備好對應的sap表格,欄位名稱和格式要確定好了。
  2. 在servlet 中也要設定這個程式何時要跑,這個就不多提了。
  3. 這個class 會繼承 TimerTask ,當servlet 設定的時間條件觸發時,便會執行。

說明 : 

  1. 本程式提供了成功、失敗寄信的考量。當失敗時會將java exception寄出。
  2. 若sap 的程式有變,只要在db 的表格中新增sap 多的欄位即可,不用動程式。
  3. 每100筆就會flush 出去,不會快速增加無用的暫存記憶體。



public void run() {
        Session s = null;
        JCoDestination jCoDestination = null;
        Transaction tx = null;
        Boolean trans_done = false;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
       
        synchronized (this) { // 一次只能有一個進程在執行
            try {    
                Boolean need_to_run = true;
                s = BaseDAO.getSession();
                tx = s.beginTransaction();
                RptLogger.logger.info("== START ==");
                RptLogger.logger.info(new Date());
                //如果沒有執行過 ,或是執行過失敗的時候會自動跑 : 有
              
                if(need_to_run){
 
                    RptLogger.logger.info("try to connect to  SAP Table ...");                                                
                    jCoDestination = ConnectSAPServer.ConnectDETest();
                    RptLogger.logger.info("connect to  SAP Table OK!");
                    JCoFunction function = jCoDestination.getRepository().getFunction("sap 提供的function name");
                    RptLogger.logger.info("get function OK!");
                    if (function == null)
                        throw new RuntimeException("function not found in SAP.");
    
                    // 傳入的參數
                    // SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
                    Calendar ca = Calendar.getInstance();
                    int this_year =  ca.get(Calendar.YEAR);
                    int this_month = ca.get(Calendar.MONTH)+1;
                    ca.add(Calendar.MONTH, -1);
                    int pre_year  = ca.get(Calendar.YEAR);
                    int pre_month = ca.get(Calendar.MONTH)+1;
                    //這邊是視你sap 程式的參數需要而加。
                    function.getImportParameterList().setValue("SALES_YEAR", this_year);
                    function.getImportParameterList().setValue("SALES_MONTH",this_month);
                    function.getImportParameterList().setValue("SALES_YACO", "COGS");
    
                    function.execute(jCoDestination);
    
                    JCoTable returnTable = function.getTableParameterList().getTable("sap 吐出來的表格名稱");
                    RptLogger.logger.info("get SAP Table OK!");
    
                    
                    List<String> header_cols = s.createSQLQuery("select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '你自己db的表格名稱'").list();
                         
                    String sql = "Insert into 你自己db的表格名稱(  ";
                    int x = 0;
                    for (String string : header_cols) {
                        sql = sql + string;
                        if (x != header_cols.size() - 1) {
                            sql = sql + ",";
                        }
                        x++;
                    }
                    x = 0;
                    sql = sql + ") values (";
                    for (String string : header_cols) {
                        sql = sql + "?";
                        if (x != header_cols.size() - 1) {
                            sql = sql + ",";
                        }
                        x++;
                    }
                    sql = sql +" ) ";
                    Query q = s.createSQLQuery(sql);
                 
                    RptLogger.logger.info("There are " + returnTable.getNumRows() + " rows to be inserted.");
                    if (returnTable.getNumRows() > 0) {
                        
                        returnTable.firstRow();
                        for (int i = 0; i < returnTable.getNumRows(); i++, returnTable.nextRow()) { // 總共幾筆資章要塞
                            x = 0;
                            for (String col : header_cols) {
                                q.setParameter(x, returnTable.getValue(col));
                                x++;
                            }
                            q.executeUpdate();
                            if (i % 100 == 0) {
                                s.flush();
                                s.clear();
                            }
                        }
                        s.flush();
                                                                       
                        tx.commit();
                        trans_done = true;
                        RptLogger.logger.info("== YURSWEBFICS END ==");
                    }
                    if(trans_done){                       
                        sendOKEmail();
                    }
                }
            } catch (Exception ex) {
                if (tx != null)
                    tx.rollback();
                ex.printStackTrace();
                StringWriter sw = new StringWriter();
                ex.printStackTrace(new PrintWriter(sw));
                RptLogger.logger.info(sw.toString());                                  
                sendWrongEmail(sw);                                                
            } finally {
                if (s != null && s.isOpen()) {
                    s.close();
                }
             
            }
        }
    }
    
    private void sendOKEmail() {
        MessageSender msender = MessageSender.getInstance();
        //寄ok信
        
    }

    private void sendWrongEmail(StringWriter sw) {
        MessageSender msender = MessageSender.getInstance();
        //寄失敗信,把java exception 寄出去,讓it可以第一時間抓到問題點。
    }
    

沒有留言:

張貼留言