728x90

실무에서 스케쥴러 작업을 하다가 새롭게 알게된 것을 정리하려고 한다. 내가 하던 작업 내용은 insert쿼리를 대략 10개 정도 수행해야 하는데 구분할 수 있는 속성이 없는 Data를 쌓는 과정에서 오류가 발생했을 때 데이터가 중간까지 쌓인다면 삭제해야하기 때문에 Java의 Trasactional을 사용하려 했다.


처음 시도한 코드는 대략 이러하다.

※ 실패코드 1

@Transactional
public void testJob() {
    dao.insert("TestSpace.insertQuery1");
    dao.insert("TestSpace.insertQuery2"); // 여기서 에러가 발생했다고 가정
    dao.insert("TestSpace.insertQuery3");
}

 - insertQuery2에서 에러가 발생했을 때 위 코드로는 전부 rollback 처리되었다. 하지만 서버에 배포 후 테스트를 했을 때 설정 문제로 자세한 에러로그가 출력되지 않았다. 이것을 해결하기위해 다음 코드를 작성했다.

 

※ 실패코드 2

@Transactional
public void testJob() {
    try {
        dao.insert("TestSpace.insertQuery1");
        dao.insert("TestSpace.insertQuery2"); // 여기서 에러가 발생했다고 가정
        dao.insert("TestSpace.insertQuery3");
    } catch(Exception e) {
        e.printStackTrace();
    }
}

 - 해당 코드에서는 에러 로그는 정상적으로 출력되었지만 트랜잭션의 특징인 원자성을 위한 rollback이 정상적으로 수행되지 않았다. 그래서 Transactional의 옵션중 rollbackFor를 사용해보기로 했다.

 

※ 실패코드 3

@Transactional(rollbackFor = Exception.class)
public void testJob() {
    try {
        dao.insert("TestSpace.insertQuery1");
        dao.insert("TestSpace.insertQuery2"); // 여기서 에러가 발생했다고 가정
        dao.insert("TestSpace.insertQuery3");
    } catch(Exception e) {
        e.printStackTrace();
    }
}

 - 해당 코드에서도 '실패코드2'의 결과와 달라진게 없다. rollbackFor = Exception.class는 Exception 예외가 발생했을 때 rollback을 수행하는 기능이다. 에러가 발생하면 Exception 예외를 던져주는 것을 추가했다.


* 성공코드

@Transactional(rollbackFor = Exception.class)
public void testJob() throws Exception {

	dao.insert("TestSpace.insertQuery4");

    try {
        dao.insert("TestSpace.insertQuery1");
        dao.insert("TestSpace.insertQuery2"); // 여기서 에러가 발생했다고 가정
        dao.insert("TestSpace.insertQuery3");
    } catch(Exception e) {
        e.printStackTrace();
        throw new Exception();
    }
}

 - Exception을 던져주는 경우 메서드 우측에 throws Exception은 try catch문 밖에 코드들의 영향을 받고 try 문은 catch문안쪽에 throw new Exception()을 추가해야하고 이것에 영향을 받는다.

 

728x90
TOP