개발자의 끄적끄적

[java & spring] 데이타 소스에 따른 속도 차이 원인 XA [펌] 본문

개발/java & jsp

[java & spring] 데이타 소스에 따른 속도 차이 원인 XA [펌]

효벨 2019. 12. 17. 11:22
728x90
반응형

[java & spring] 데이타 소스에 따른 속도 차이 원인 XA [펌]

 

만건을 인서트해야 하는데, ibatis에서도 addBatch가 된다는 것을 알고 testIbatis() 메소드처럼 테스트 함수를 만들었다.

잉 그런데 45초 이상이 걸리는 것이었다. 왜그렇지?

그래서 testJdbc() 함수를 만들어봤는데 같은 3만건인데도 0초도 안 걸리는 것이었다.

 

아 왜그럴까? 여러가지 고민을 하고, 찾아보고, 테스트도 해봤는데 답이 안 나오는 것이었다.

 

그러다가 혹시나해서 testJdbc()에서 아래처럼 conn부분을 바꿔봤다.

//iBatis의 dataSourse사용
conn = sqlMapClientTemplate.getDataSource().getConnection();

 

그랬더니 0초도 안 걸리던 testJdbc() 가 70초 이상되도 끝나지 않는 것이었다.

 

혹시 dataSource 문제인가 싶어서,  아래처럼 jndi에서 직접 입력으로 변경해보았다.

<!-- jndi를 쓸 경우 . 기존꺼.
  <jee:jndi-lookup id="dataSource" jndi-name="weblogicDataSource"/>
  -->
  
   <!-- //Oracle -->
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
  <property name="url" value="jdbc:oracle:thin:@localhost:1521:test"/>
  <property name="username" value="test"/>
  <property name="password" value="1234"/>
  </bean> 

 

그러니까 testJdbc()도 0초, testIbatis()도 0초가 걸리더라.

 

아무래도 jndi 트랜젝션을 사용하면 뭔가 퍼포먼스가 그지가 되던가, 아니면 was의 jndi설정를 바꿔줘야 하나보다.

 

이런 문제로 해메는 사람들이 있을 까봐 포스팅해본다. 아래는 소스들은 참고하시랴.

 

현재 상황에서 was의 jndi를 반드시 사용해야 하므로..  좀 더 알아봐야 겠다......

 

---------------------2011년 5월 23일 ---------------------------------------------------

 

문제는 해결했다. 원인은 jndi와 스프링 트랜젝션 설정이 글로벌(혹은 XA) 트랜젝션으로 잡혀있었다는 것이다.

다행히 난 하나의 디비만 상대해서 글로벌 설정을 다 해제하고 로컬 트랜젝션으로 재설정하니 속도가 매우

빨라졌다.  전역 혹은 분산 트랜젝션 할 경우 속도를 위해 커스텀마이징 하는 것도 있다는 하는데

 지금은 필요없으니 나중에 공부하고, 지금은 로컬 트랜젝션으로 설정해서 진행해야 겠다.

 

jndi에서 오라클 드라이버를 선택할 때, XA용으로 선택하지 말긔.

jndi에서 글로벌 트랜젝션 지원해달라고 설정하지 말긔.

스프링 설정에서 jndi 설정할때  jee로 데이터소스 설정하지 말긔.

스프링 설정에서 jta트랜젝션으로 설정하지 말긔.

 

=======================================================================================

 

/**
     * 메시지 insert
     * ibat
     * @param mm CommMessage
     * @return map
     */
    public void testIbatis() {
        logger.debug("##################################################################");
        long transStart = 0;
       
        try {
           
            transStart = System.currentTimeMillis();
            sqlMapClientTemplate.getSqlMapClient().startTransaction();
           
            sqlMapClientTemplate.getSqlMapClient().startBatch();
           
            Map<String, String> pMap = null;
            long a = System.currentTimeMillis();
            for (int i = 0; i < 30000; i++) {
                pMap = new HashMap<String, String>();
                pMap.put("p1", i + "");
                pMap.put("p2", i + "");
                pMap.put("p3", i + "");
                pMap.put("p4", i + "");
                pMap.put("p5", i + "");
                sqlMapClientTemplate.getSqlMapClient().insert("message.test", pMap);
                //sqlMapClientTemplate.insert("message.test", pMap);
                pMap.clear();
                pMap = null;
            }
           
            long b = System.currentTimeMillis();
            logger.debug("/////////////////////////////////////////////// executeBatch before()" +(Math.floor((b - a) / 1000)));
            sqlMapClientTemplate.getSqlMapClient().executeBatch();
            long c = System.currentTimeMillis();
            logger.debug("/////////////////////////////////////////////// executeBatch after()" +(Math.floor((c - b) / 1000)));
           
            /* //또다른 방법 ㅠㅠ
            sqlMapClientTemplate.execute(new SqlMapClientCallback() {
                public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
                    executor.startBatch();
                    Map<String, String> pMap = new HashMap<String, String>();
                    long a = System.currentTimeMillis();
                    for (int i = 0; i < 30000; i++) {
                        executor.insert("message.test");
                    }
                    long b = System.currentTimeMillis();
                    logger.debug("/////////////////////////////////////////////// executeBatch before()" +(Math.floor((b - a) / 1000)));
                    executor.executeBatch();
                    long c = System.currentTimeMillis();
                    logger.debug("/////////////////////////////////////////////// executeBatch after()" +(Math.floor((c - b) / 1000)));
                    return null;
                }
            });
            */
           
            sqlMapClientTemplate.getSqlMapClient().commitTransaction();
            //sqlMapClientTemplate.getSqlMapClient().getCurrentConnection().commit();
            long transCommit = System.currentTimeMillis();
           
            logger.debug("test 총 트랜젝션 시간 transCommit: " + (Math.floor((transCommit - transStart) / 1000)));
           
           
        } catch (Exception e) {
            logger.debug("[" + this.getClass().getName() + ".insertMessage] " + e.toString());
            throw new RuntimeException(e);
        } finally {
            try {
                sqlMapClientTemplate.getSqlMapClient().endTransaction();
               
            } catch (SQLException e) {
                e.printStackTrace();
            }
           
            long transEnd = System.currentTimeMillis();
           
            logger.debug("test 총 트랜젝션 시간 end: " + (Math.floor((transEnd - transStart) / 1000)));
           
            logger.debug(log.toString());
            logger.debug("##################################################################");
        }
       
    }
   
    public void testJdbc(){
       
       
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            String url = "jdbc:oracle:thin:@localhost:1521:test";
            String user ="test";
            String passwd = "1234";
            conn = DriverManager.getConnection(url, user, passwd);
            
            //iBatis의 dataSourse사용
            //conn = sqlMapClientTemplate.getDataSource().getConnection();
           

            conn.setAutoCommit(false);
            String sql = "insert into dobatch values ( ?, ?, ?, ?, ?) ";
            pstmt = conn.prepareStatement(sql);
            long s = System.currentTimeMillis();
            for (int i=0; i<30000; i++) {
                pstmt.setString(1, "col1");
                pstmt.setString(2, "col2");
                pstmt.setString(3, "col3");
                pstmt.setString(4, "col4");
                pstmt.setString(5, "col5");
                pstmt.addBatch();
            }
            long b = System.currentTimeMillis();
            logger.debug("/////////////////////////////////////////////// executeBatch before()" +(Math.floor((b - s) / 1000)));
            pstmt.executeBatch();
            long c = System.currentTimeMillis();
            logger.debug("/////////////////////////////////////////////// executeBatch after()" +(Math.floor((c - b) / 1000)));
           
            conn.commit();
            long e = System.currentTimeMillis();
           
            logger.debug("testJdbc 총 트랜젝션 시간 transCommit: " + (Math.floor((e - s) / 1000)));

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                pstmt.close();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
       
    }

[출처] ibatis에서 addBatch 사용할 경우...|작성자 창조시간

 

출처 : https://m.blog.naver.com/PostView.nhn?blogId=leeyoon0607&logNo=70118808232

반응형
Comments