티스토리 뷰

Spring Framework는 트랜잭션을 적용하기 위해 다양한 방법을 제공한다. 해당 글에서는 선언적 트랜잭션 방법에 대해서 설명하고자 한다.

TransactionManager 지정

Spring에서 제공하는 트랜잭션 기능을 사용하기 위해 TransactionManager를 bean 객체로 등록해줘야 한다.
TransactionManager를 bean 객체로 등록 시 dataSource라는 property에 dataSource 객체를 등록해 준다.

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:advice> 태그 사용

Spring으로 트랜잭션 기능을 사용하기 위한 방법 중 하나는 <tx:advice> 태그를 사용하는 것이다.
<tx:advice>, <tx:attributes>, <tx:method>를 사용하여 트랜잭션 관련 설정을 지정한다.
<tx:advice> 태그는 트랜잭션을 적용할 때 사용하는 Advisor를 생성한다. transaction-manager 속성에는 TransactionManager bean을 설정한다.

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="order" propagation="REQUIRED" />
        <tx:method name="get*" read-only="true"/>
    </tx:attributes>
</tx:advice>

위 설정만으로 트랜잭션이 적용되는 것은 아니고, 실제로 트랜잭션을 적용하는 것은 AOP를 통해서 이뤄진다.

<aop:config>
    <aop:pointcut id="servicePublicMethod" expression="execution(public * com.sample.myapp..*Service.*(..))"/>
      <sop:advisor advice-ref="txAdvice" pointcut-ref="servicePublicMethod"/>
</aop:config>

위 설정은 <aop:config> 태그를 이용해서 com.sample.myapp 패키지의 하위 패키지에 있는 *Service의 public 메서드에 <tx:advice>로 설정한 트랜잭션을 적용하도록 설정하고 있다. <tx:method> 태그에서 이름이 "order", "get*" 메서드에만 트랜잭션을 적용했기 때문에 실제로는 해당 메서드를 호출할 때만 트랜잭션이 적용된다.

@Transactional 사용

2번째 방법으로는 @Transactional 어노테이션을 사용하는 것이다. 태그 설정보다는 좀 더 간편하여 사용성이 좋다.
@Transactional을 사용하기 위해서는 <tx:annotation-driven> 태그를 설정해야 한다.

<tx:annotation-dirven transaction-manager="transactionManager"/>

java 코드 기반으로 설정을 지정한다면 @EnableTransactionManagement를 추가해줘야 한다.

@Configuration
@EnableTransactionManagement
@ImportResource("classpath:dataSource.xml")
public class Config {

    @Autowired
    private DataSource dataSource;

    @Bean
    public PlatformTransactionManager txManager() {
        DataSourceTransactionManager txMgr = new DataSourceTransactionManager();
        txMgr.setDataSource(dataSource);
        return txMgr;
    }
}

@Transactional 어노테이션 주요 속성

@Transactional은 트랜잭션 지정 시 다양한 속성을 제공한다. 제공하는 속성을 사용하여 트랜잭션을 세밀하게 제어할 수 있다.

속성 설명
propagation 트랜잭션 전파 규칙을 설명한다.
org.springframework.annotation.Propagation 열거형 타입에 값이 정의되어 있다.
기본 값은 Propagation.REQUIRED 이다.
isolation 트랜잭션 격리 레벨을 설정한다.
org.springframework.annotation.Isolation 열거형 타입에 값이 정의되어 있다.
readOnly 읽기 전용 여부를 설정한다. boolean 값을 설정하며, 기본값은 false이다.
rollbackFor 트랜잭션을 롤백할 익셉션 타입을 설정한다.
예) rollbackFor={Exception.class}
noRollbackFor 트랜잭션을 롤백하지 않을 익셉션 타입을 설정한다.
예) noRollbackFor={ItemNotFoundException.class}
timeout 트랜잭션의 타임아웃 시간을 초 단위로 설정한다.

설정 적용 예시

@Transactional(propagation=Propagation.REQUIRED)
public void order(Map param) {
    ...
}

Spring Transaction 동작 과정

<tx:advice>@Transactional을 사용하여 Transaction을 적용하는 경우 Spring의 AOP를 사용하여 Transaction이 적용된다. 트랜잭션을 처리하기 위해 프록시 객체가 생성되고 프록시 객체는 PlatformTransactionManager를 이용하여 트랜잭션을 시작한 뒤에 비즈니스 로직이 있는 메서드를 실행하고 PlatformTransTransactionManager를 이용해서 트랜잭션을 커밋한다.

Transaction 전파 레벨 및 격리 수준 설정

Spring은 트랜잭션 실행 시 다른 트랜잭션이 실행하는 경우 트랜잭션의 전파여부에 대한 설정을 제공한다. 또한, 트랜잭션의 격리성 수준도 속성을 Transaction 속성을 통해 제어할 수 있다.

전파 레벨 설정

옵션 설명
REQUIRED 메서드가 실행될 때 트랜잭션이 필요함을 의미
현재 진행중인 트랜잭션이 있으면 해당 트랜잭션을 사용하고 없으면 새로운 트랜잭션을 생성함
MANDATORY 메서드를 수행할 때 트랜잭션이 필요함을 의미
REQUIRED와 달리 진행중인 트랜잭션이 존재하지 않는 경우 익셉션 발생
REQUIRES_NEW 항상 새로운 트랜잭션 시작
기존 트랜잭션이 존재하면 기존 트랜잭션을 중지하고 새로운 트랜잭션 시작
새로 시작된 트랜잭션이 종료하면 중지된 기존 트랜잭션 재개
SUPPORTS 메서드 실행 시 트랜잭션이 필요 하진 않지만 기존 트랜잭션이 존재하는 경우 트랜잭션을 사용한다는 것을 의미
NOT_SUPPORTED 메서드가 트랜잭션을 필요로 하지 않음을 의미
SUUPPORTS와 달리 진행중인 트랜잭션이 존재하는 경우 메서드가 실행되는 동안 트랜잭션은 일시 중지되며 메서드 실행이 종료된 후에 트랜잭션을 계속 진행
NEVER 메서드가 트랜잭션을 필요로 하지 않으며, 만약 진행중인 트랜잭션이 존재하면 익셉션을 발생시킴
NESTED 기존 트랜잭션이 존재하면, 기존 트랜잭션에 중첩된 트랜잭션에서 메서드를 실행
기존 트랜잭션이 존재하지 않으면 REQUIRED와 동일하게 동작

격리 수준 설정

옵션 설명
DEFAULT 기본 설정 사용
READ_UNCOMMITTED 다른 트랜잭션에서 커밋하지 않은 데이터를 읽을 수 있음
READ_COMMITTED 다른 트랜잭션에 의해 커밋된 데이터를 읽을 수 있음
REPEATABLE_READ 처음에 읽어온 데이터와 두번째 읽어온 데이터가 동일한 값을 가짐
SERIALZABLE 동일한 데이터에 대해서 동시에 두 개 이상의 트랜잭션이 수행될 수 없음

결론

Spring Framework는 다양한 방법으로 트랜잭션을 선언적으로 적용할 수 있도록 지원하며 xml 기반 설정(<tx:advice>)과 어노테이션 기반 설정(@Transactional) 모두 AOP와 함께 동작한다. 복잡한 비즈니스 로직에서 데이터 정합성을 유지하기 위해서는 전파레벨(propagation)과 격리 수준(isolation)을 상황에 맞게 세밀하게 설정하는 것이 중요하다.

어노테이션 방식은 간결하여 유지보수 및 사용성이 좋고, XML 방식은 공통적인 트랜잭션 규칙을 모듈 단위에 일괄적으로 적용할 때 유용하다.

따라서, 상황에 따라 적절한 방식을 선택하고, 트랜잭션의 동작 방식과 예외 처리 규칙을 잘 이해한다면 안정적인 트랜잭션 기반 시스템을 구축할 수 있다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/05   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함