트랜잭션 동기화

jooog·2022년 6월 28일
0

스프링DB

목록 보기
8/13

🎨 PlatformTransactionManager

스프링이 제공하는 'PlatformTransactionManager'는 크게 두가지 역할을 한다. 첫번째는 트랜잭션을 추상화하는 것이고 그 다음으로는 리소스를 동기화하는 것이다.

🎨 리소스 동기화

트랜잭션을 유지하려면 트랜잭션이 시작될 때부터 끝까지 같은 데이터베이스의 커넥션을 유지해야 한다. 하지만 파라미터로 매번 커넥션을 전달하는 방식을 사용하면 코드가 지저분해지고 유지보수가 힘들어지는 등 여러가지 단점이 많다. 그렇다면 어떤 방법으로 트랜잭션을 일관되게 만들 수 있을까?

스프링은 트랜잭션 동기화 매니저를 제공하는데 이 동기화 매니저는 쓰레드 로컬(ThreadLocal)을 사용해서 커넥션을 안전하게 보관하고 동기화해주는 역할을 한다. 따라서 동기화 매니저를 사용하면 멀티쓰레드 환경에서도 안전하게 커넥션을 동기화할 수 있고 커넥션이 필요할때는 파라미터로 커넥션을 전달하지 않아도 동기화 매니저를 통해 획득할 수 있다.

🎨 DataSourceUtils

트랜잭션 동기화 기능을 사용하기 위해 스프링이 제공하는 DataSourceUtils를 사용한다.

private Connection getConnection() throws SQLException {

        //스프링이 제공하는 DataSourceUtils
        //DataSourceUtils로 트랜잭션 동기화 사용 가능
        Connection con = DataSourceUtils.getConnection(dataSource);

        log.info("get connection={} class={}", con, con.getClass());
        return con;
    }

DataSourceUtils.getConnection을 따라가서 자세히 살펴보면 트랜잭션 동기화 매니저에 보관된 커넥션을 꺼내오는 것을 확인할 수 있다.

커넥션을 닫을때도 DataSourceUtils의 releaseConnection을 사용한다.

private void close(Connection con, Statement stmt, ResultSet rs) {
        JdbcUtils.closeResultSet(rs);
        JdbcUtils.closeStatement(stmt);

        DataSourceUtils.releaseConnection(con, dataSource);
   //     JdbcUtils.closeConnection(con);
    }

🎨 DataSourceUtils.getConnection

DataSourceUtils.getConnection으로 커넥션을 호출하면 트랜잭션 동기화 매니저는 보관하고 있는 커넥션이 있는 경우에는 해당 커넥션을 반환하고 없다면 새로운 커넥션을 생성해서 반환한다.

🎨 DataSourceUtils.releaseConnection

커넥션을 close해서 직접 닫아버리면 커넥션이 유지되지 않는 문제가 발생한다. 커넥션은 트랜잭션이 종료(커밋 or 롤백) 될 때까지 살아있어야 하기 때문이다. 이때 DataSourceUtils.releaseConnection을 사용하면 커넥션을 바로 닫지 않고 동기화된 커넥션은 그대로 유지해준다. 하지만 트랜잭션 동기화 매니저가 관리하는 커넥션이 없는 경우에는 해당 커넥션을 닫는다.

이 글은 김영한님의 스프링 DB 1편 - 데이터 접근 핵심 원리 강의를 듣고 정리한 내용입니다.

0개의 댓글