2024년 6월 6일 목요일

Spring Boot와 MyBatis 환경에서 롤백이 되지 않는 문제

 상황은 여러 개의 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 어노테이션은 필요 없을 것 같다.