개요
배치 작업을 맡고 난 뒤 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 만들기 끝..
결국 지긋하게 멍청한건 나였다..
'Spring' 카테고리의 다른 글
[Spring] 전체 흐름 정리 (0) | 2023.11.28 |
---|---|
[Spring] 새로운 구조와 할인 정책 적용 (0) | 2023.11.28 |
[Spring] 관심사의 분리, AppConfig (1) | 2023.11.28 |
[Spring] 프로젝트 생성 (1) | 2023.10.30 |
[Spring] 객체지향 설계와 스프링 (37) | 2023.10.30 |