[ Mybatis ] sqlSession 이용해서 commit 수동만들기

개요

배치 작업을 맡고 난 뒤 35만건 까지는 mybatis <foreach>문으로 어떻게든 만회했으나..

4000만건 이상의 데이터를 배치작업 해야할수도 있는 상황이 생겨서 트랜젝션 관련 고민을 하게 되었다.

그래서 모든 동작이 끝나고 난 뒤 commit 하는 방식 대신, 수동으로 만들어서 for문 돌면서 insert 해줄때마다 commit을 수동으로 해주는 방법을 해야겠다고 생각했다.

1차로 작성한 코드

public Boolean excuteJob (){ 
Boolean result = false;
List<exampleVo> exampleVo = new ArrayList<>();
try{
mybatisEdbConfig.edbSqlSessionTemplate().getConnection();
deleteMenualTransactionExample();

//초기값 세팅
int count = 1;
int offset = 1;
int limit = 1900;
int totalCount = oraExampleSVC.selectAll();
int repeatCnt = totalCount % limit == 0 ? totalCount/limit:limit+1;

for(count =1;count<=repeatCnt;count++){
limit = count != repeatCnt ? 1899+offset :totalCount;
List<exampleVo> list  = oraExampleSVC.selectEx(ExampleVo,count,offset,limit,repeatCnt,totalCnt);
insertMenualTransactionExample(list);
offset = limit +1;
}
result = count>=repeatCnt ? true:false;
mybatisEdbConfig.edbSqlSessionTemplate().close();
} catch(Exception e){
e.printStacjTrace();
} finally{
result==null?false:true;
}
return result;
}

@Transactional
void deleteMenualTransactionExample() throws Exception{
 mybatisEdbConfig.edbSqlSessionTemplate().delete("~~~.dao.edb.deleteAllExample01");
}

@Transactional
void insertMenualTransactionExample(List list){
 mybatisEdbConfig.edbSqlSessionTemplate().insert("~~~.dao.edb.bulkInsertExample01");
}

 

1차로 작성하는 과정에서 < transaction is already completed > 오류의 무한굴레에 빠져서 멘붕이 왔지만

대리님이 각각의 쿼리문을 함수로 빼서 각각 transactional을 걸어주시는 마법을 부려주셨다.

 

그렇게 해서 실행을 해 보니 쿼리 돌때마다 실시간으로 commit이 잘 되었지만 빠져나오는 구문에서

<manual close is not allowed over a spring managed sqlsession> 이라는 오류가 나왔다

최종적으로 배치작업은 다 끝난 후에 오류가 나와서 작동에는 문제가 없긴 하지만,, 그래도 오류를 해결해야하기 때문에 찾아보니 sqlSession 을 사용하는거면 닫아주는게 맞는데 sqlSessionTemplate 를 이용하는거면 자동으로 닫혀서 닫아줄 필요가 없단다 .. 

그래서 close() 해주는 부분을 주석처리 해주면  ?

새로운 오류가 난다  ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ

진짜 배치작업 나랑 한판 뜨자

해결되는대로 글을 업데이트 해보도록 하겠다..

최종 코드

public Boolean excuteJob (){ 
Boolean result = false;
List<exampleVo> exampleVo = new ArrayList<>();

deleteMenualTransactionExample();
//초기값 세팅
int count = 1;
int offset = 1;
int limit = 1900;
int totalCount = oraExampleSVC.selectAll();
int repeatCnt = totalCount % limit == 0 ? totalCount/limit:limit+1;

for(count =1;count<=repeatCnt;count++){
limit = count != repeatCnt ? 1899+offset :totalCount;
List<exampleVo> list  = oraExampleSVC.selectEx(ExampleVo,count,offset,limit,repeatCnt,totalCnt);
insertMenualTransactionExample(list);
offset = limit +1;
}
result = count>=repeatCnt ? true:false;
return result;
}


@Transactional
void deleteMenualTransactionExample() throws Exception{
 mybatisEdbConfig.edbSqlSessionTemplate().delete("~~~.dao.edb.deleteAllExample01");
}

@Transactional
void insertMenualTransactionExample(List list){
 mybatisEdbConfig.edbSqlSessionTemplate().insert("~~~.dao.edb.bulkInsertExample01");
}

sqlSession일때는 commit(),rollback(),close()가 가능하지만

sqlTemplate일때는 이 모든것이 자동으로 이루어져서

그냥 의존성 주입만 해주고 사용하면 되는 일이었다..!

그렇게 험난했던 수동commit 만들기 끝..

결국 지긋하게 멍청한건 나였다..