프로그래밍/SPRING

[SPRING] 스프링 Transactional Checked예외 설정과 테스트

테렌테렌 2022. 4. 1. 09:48

# 출처 : 남궁성의 스프링의 정석

 

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int remove(Integer cno, Integer bno, String commenter) throws Exception {
        int rowCnt = boardDao.updateCommentCnt(bno, -1);
        System.out.println("updateCommentCnt - rowCnt = " + rowCnt);
//        throw new Exception("test");
        rowCnt = commentDao.delete(cno, commenter);
        System.out.println("rowCnt = " + rowCnt);
        return rowCnt;
    }

위 소스는 Service 단계에서 댓글을 삭제하는 로직이다.

댓글 삭제의 경우 댓글갯수를 줄이고 댓글을 지우는 두가지 작업이 다 성공 해야 한다.

그래서 메서드에 @Transactional애너테이션이 걸려 있다.

 

@Transactional(rollbackFor = Exception.class)

Checked예외로 Exception.class 즉 Exception의 자손들 예외가 발생 하면 롤백 하도록 rollbackFor를 지정.

기본 적으로는 Runtime예외들은 롤백을 하는데 이렇게 Checked예외 같은 경우는 롤백을 안해서 지정을 해줬다.

 

//        throw new Exception("test");

문장 같은 경우는 첫번째 출력만 처리하고 롤백이 되는지 보려고 일부러 예외를 발생 시켰다.

 

 

이제 테스트를 해보자.

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int remove(Integer cno, Integer bno, String commenter) throws Exception {
        int rowCnt = boardDao.updateCommentCnt(bno, -1);
        System.out.println("updateCommentCnt - rowCnt = " + rowCnt);
        throw new Exception("test");
//        rowCnt = commentDao.delete(cno, commenter);
//        System.out.println("rowCnt = " + rowCnt);
//        return rowCnt;
    }

CommentServiceImpl의 댓글을 삭제하는 테스트에서 일부러 예외를 발생 시켰다.

"board 테이블의 comment_cnt 값을 -1 줄이고 오류가 발생 해서 롤백이 되어야 성공"

 

@Test
public void remove() throws Exception {
    boardDao.deleteAll();

    BoardDto boardDto = new BoardDto("hello", "hello", "asdf");
    assertTrue(boardDao.insert(boardDto) == 1);
    Integer bno = boardDao.selectAll().get(0).getBno();
    System.out.println("bno = " + bno);

    commentDao.deleteAll(bno);
    CommentDto commentDto = new CommentDto(bno,0,"hi","qwer");

    assertTrue(boardDao.select(bno).getComment_cnt() == 0);
    assertTrue(commentService.write(commentDto)==1);
    assertTrue(boardDao.select(bno).getComment_cnt() == 1);

    Integer cno = commentDao.selectAll(bno).get(0).getCno();

    // 일부러 예외를 발생시키고 Tx가 취소되는지 확인해야.
    int rowCnt = commentService.remove(cno, bno, commentDto.getCommenter());
    assertTrue(rowCnt==1);
    assertTrue(boardDao.select(bno).getComment_cnt() == 0);
}

CommentServiceImplTest에서 테스트를 진행 해보자.

 

remove 테스트 메서드를 실행

44번 Line에서 오류가 발생한 모습

오류 발생 후 DB를 확인

board 테이블 결과
comment 테이블 결과

 

댓글 삭제 단계에서 오류가 발생하여 board 테이블의 comment_cnt 값이 줄어 들지 않았다.

 

다시 예외를 주석 걸고 아래 주석을 해제한 뒤 실행 해보면 정상적으로 comment_cnt 값이 줄어 든 것이 확인 되었다.