-
@TransactionSpring&SpringBoot 2025. 11. 13. 08:39
트랜잭션 추상화
// JDBC 트랜잭션 코드 예시 public void accountTransfer(String fromId, String toId, int money) throws SQLException { Connection con = dataSource.getConnection(); try { con.setAutoCommit(false); //트랜잭션 시작 //비즈니스 로직 bizLogic(con, fromId, toId, money); con.commit(); //성공시 커밋 } catch (Exception e) { con.rollback(); //실패시 롤백 throw new IllegalStateException(e); } finally { release(con); } } // JPA 트랜잭션 코드 예시 public static void main(String[] args) { //엔티티 매니저 팩토리 생성 EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook"); EntityManager em = emf.createEntityManager(); //엔티티 매니저 생성 EntityTransaction tx = em.getTransaction(); //트랜잭션 기능 획득 try { tx.begin(); //트랜잭션 시작 logic(em); //비즈니스 로직 tx.commit();//트랜잭션 커밋 } catch (Exception e) { tx.rollback(); //트랜잭션 롤백 } finally { em.close(); //엔티티 매니저 종료 } emf.close(); //엔티티 매니저 팩토리 종료 }- JDBC 트랜잭션에 의존하다가 JPA 기술로 변경하게 되면 서비스 계층의 트랜잭션을 처리하는 코드도 모두 함께 변경해야 한다
스프링의 트랜잭션 추상화

- 스프링 트랜잭션 추상화의 핵심은 PlatformTransactionManager 인터페이스
- org.springframework.transaction.PlatformTransactionManager
트랜잭션 동기화
스프링이 제공하는 트랜잭션 매니저
- 트랜잭션 추상화
- 리소스 동기화

- 스프링은 트랜잭션 동기화 매니저를 제공한다
- 트랜잭션 동기화 매니저는 쓰레드 로컬을 사용하여 커넥션을 동기화한다 따라서 멀티쓰레드 환경에서 안전하게 커넥션을 동기화할 수 있다
트랜잭션 매니저의 전체 동작 흐름

- 클라이언트 요청으로 서비스 로직 시작
- 서비스 계층에서 transactionManger.getTransaction()을 호출해 트랜잭션 시작
- 트랜잭션 매니저는 내부에서 데이터소스를 사용해서 커넥션 생성
- 커넥션을 수동 커밋모드로 변경해서 실제 데이터베이스 트랜잭션 시작
- 커넥션을 트랜잭션 동기화 매니저에 보관
- 트랜잭션 동기화 매니저는 쓰레드 로컬에 커넥션 보관

- 서비스는 비즈니스 로직 실행하면서 리포지토리 메서드 호출
- 리포지토리 메서드는 트랜잭션이 시작된 커넥션이 필요하기 때문에 DataSourceUtils.getConnection() 사용해 트랜잭션 동기화 매니저에 보관된 커넥션을 꺼내 사용
- 획득한 커넥션을 통해 SQL을 DB에 전달 후 실행

- 비즈니스 로직 끝나면 트랜잭션을 종료하고 트랜잭션은 커밋/롤백하면 종료
- 트랜잭션을 종료하기 위해 동기화된 커넥션이 필요해 트랜잭션 동기화 매니저를 통해 동기화된 커넥션을 획득
- 획득한 커넥션을 통해 데이터베이스에 트랜잭션을 커밋하거나 롤백
- 전체 리소스 정리
트랜잭션 템플릿
public class TransactionTemplate { private PlatformTransactionManager transactionManager; public <T> T execute(TransactionCallback<T> action){..} void executeWithoutResult(Consumer<TransactionStatus> action){..} }트랜잭션 AOP

- 프록시를 사용하면 트랜잭션을 처리하는 객체와 비즈니스 로직을 처리하는 서비스 객체를 명확히 분리할 수 있다
- 스프링이 제공하는 트랜잭션 AOP - @Transactional 애노테이션
- org.springframework.transaction.annotation.Transactional

- 트랜잭션 AOP 적용 전체 흐름
- 선언적 트랜잭션 관리(Declarative Transaction Management)
데이터소스, 트랜잭션 매니저 직접 등록
# application.properties spring.datasource.url=jdbc:h2:tcp://localhost/~/test spring.datasource.username=sa spring.datasource.password=@Slf4j @SpringBootTest class MemberServiceV3_4Test { @TestConfiguration static class TestConfig { private final DataSource dataSource; public TestConfig(DataSource dataSource) { this.dataSource = dataSource; } @Bean MemberRepositoryV3 memberRepositoryV3() { return new MemberRepositoryV3(dataSource); } @Bean MemberServiceV3_3 memberServiceV3_3() { return new MemberServiceV3_3(memberRepositoryV3()); } } ... }- 스프링부트가 application.properties에 지정된 속성을 참고해서 데이터소스와 트랜잭션 매니저를 자동으로 생성한다
- 프로그래밍 방식의 트랜잭션 관리(programmatic transaction management)
- 테스트 시에 가끔 사용
728x90'Spring&SpringBoot' 카테고리의 다른 글
데이터 접근 기술 - 스프링 데이터 JPA (0) 2025.11.20 트랜잭션 커밋/롤백과 예외 (0) 2025.11.20 트랜잭션, DB 락 (0) 2025.11.12 JDBC (0) 2025.11.12 스프링 AOP 실무 주의사항 (0) 2025.10.21