상황은 여러 개의 insert가 있는 경우, 앞의 쿼리는 정상적으로 insert되었지만
뒤의 insert가 실패할 때 앞의 쿼리가 롤백되지 않고 insert된 상태로 남아 있는 문제였다.
원인은 MyBatis의 autocommit이 기본적으로 true로 설정되어 있어 발생한 문제였다.
쿼리가 실행될 때마다 autocommit이 실행되어 롤백이 되지 않는 현상이 있었다.
해결책으로는 SqlSessionFactory
를 직접 받아서 autocommit을 false로 설정하고,
try-catch 블록을 사용해 명시적으로 롤백을 선언하는 방법을 사용했다.
// SqlSessionFactory를 주입받습니다.
private final SqlSessionFactory sqlSessionFactory;
...
@Transactional(rollbackFor = Exception.class)
public void 메소드() {
// autocommit을 false로 설정하여 SqlSession을 생성합니다.
SqlSession sqlSession = sqlSessionFactory.openSession(false);
try {
// 여러 insert 작업을 수행합니다.
insert;
insert;
} catch (Exception ex) {
// 예외 발생 시 롤백을 수행합니다.
sqlSession.rollback();
throw new RuntimeException(ex);
} finally {
// 세션을 닫아줍니다.
sqlSession.close();
}
}
SqlSession을 통해 직접 롤백 처리를 했기 때문에 @Transactional
어노테이션은 필요 없을 것 같다.