ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring - 트랜잭션 처리하기
    Spring 2019. 2. 25. 23:29

    스프링에서 트랜잭션 처리는 트랜잭션 매니저를 이용하여 한다.
    AOP 를 이용하기 때문에 pom.xml 에 AspectJ가 등록되어 있어야 한다.

    <!-- AspectJ -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${org.aspectj-version}</version>
    </dependency>    
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
            <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>${org.aspectj-version}</version>
    </dependency>

    어노테이션을 이용한 트랜잭션 처리

    root-context.xml

    root-context.xml에 가서 네임스페이스에서 tx를 선택한다.

    그 후 트랜잭션 매니저 bean을 만들고 tx:annotaion-driven을 작성한다.

    <bean id="transaciontManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>

    그 후 트랜잭션 처리를 해야하는 서비스의 메소드 위에 @Transactional 어노테이션을 작성한다.

    적용이 되면 왼쪽에 화살표 표시가 생긴다.

    선언적 처리를 이용한 트랜잭션 처리

    root-context.xml

    root-context 네임스페이스에서 tx를 선택해준다.
    그 후 tx 엘리먼트를 작성한다.
    먼저 트랜잭션 매니저를 정의한다.

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

    트랜잭션의 대상을 설정한다.

        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="select*" rollback-for="Exception" read-only="true"/>
                <tx:method name="update*" rollback-for="Exception"/>
                <tx:method name="insert*" rollback-for="Exception"/>
                <tx:method name="delete*" rollback-for="Exception"/>
            </tx:attributes>
        </tx:advice>

    tx:method 는 트랜잭션의 대상이 되는 메소드를 정의한 것이다.
    select* 은 select로 시작하는 메소드를 의미한다.

    <aop:config>
        <aop:pointcut expression="execution(* com.tset.spring..*ServiceImpl.*(..))" id="serviceMethod"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" id="transactionAdvisor"/>
    </aop:config>

    그 후 AOP를 통해 트랜잭션의 포인트 컷을 설정한다.

    두 가지 방법 중 하나를 이용하여 트랜잭션 처리를 해주면 된다.

    옵션

    어노테이션으로 처리하는 경우는 @Transacional(옵션) 방식이며 선언적 처리로 하는 경우는 tx:method를 작성할 때 옵션을 넣어준다.

    옵션은 다음과 같다.

    옵션 이름 설명
    readonly 읽기 전용(select 처리시)
    isolation 트랜잭션 자체 독립성, 여러 트랜잭션이 작업할 때 작업에 대한 결과를 어떻게 처리할 지에 대해 결정한다.
    propagation 트랜잭션 전파, 여러 메소드의 수행을 하나의 트랜잭션으로 처리할 것인지 설정한다.
    timeout 트랜잭션의 제한시간을 설정한다. default: -1 (제한 시간 없음)
    rollback-for 특정 예외가 발생할 경우 rollback 처리를 한다 (default: RuntimeException)
    no-rollback-For 특정 예외가 발생하더라도 rollback 처리를 하지 않는다.

    propagation의 옵션

    옵션 이름 설명
    REQUIRED default, 부모 트랜잭션이 있으면 참여하고 없으면 새로 생성한다.
    SUPPORT 부모 트랜잭션이 있으면 참여하고 없으면 생성하지 않고 정상적으로 수행한다.
    MANDATORY 부모 트랜잭션이 있으면 없으면 예외처리한다. 독립적인 트랜잭션이 생기는 것을 방지한다.
    REQUIRED_NEW 항상 새로운 트랜잭션을 생성한다.
    NOT_SUPPORTED 트랜잭션 사용 안 함, 실행 중인 트랜잭션이 있으면 보류한다.
    NEVER 트랜잭션 사용 안 함, 실행 중인 트랜잭션이 있으면 예외처리한다.
    NESTED 중첩 트랜잭션, 실행 중인 트랜잭션 위에 새로운 트랜잭션이 생성된다. 자식 트랜잭션이 부모에게 영향을 주지 않고 자신만 트랜잭션 처리되며 부모가 트랜잭션 처리되면 자식도 함께 처리된다.

    isolation의 옵션

    옵션 이름 설명
    read_uncommitted 가장 낮은 수준의 격리, 트랜잭션이 완료되기 전에 다른 트랜잭션이 읽을 수 있다.
    read_committed default, 트랜잭션이 커밋되면 읽을 수 있다. 읽은 정보를 수정 가능하다.
    repeatable_read 트랜잭션이 커밋되면 읽을 수 있다. 읽은 정보를 수정 불가능하다.
    serializable 가장 강력한 격리, 한번에 트랜잭션 하나씩 처리한다.

    어노테이션에서 옵션 사용 예시

    @Transactional(
    propagation=Propagation.REQUIRED,
    readOnly = true,
    rollbackFor=Exception.class,
    noRollbackFor=Exception.class,
    timeout = 10
    isoloation = Isolation.READ_COMMITTED
    )

    tx:method 에서 옵션 사용 예시

    <tx:method name="select*" read-only="true" rollback-for="Exception" propagation="REQUIRED" isolation="READ_COMMITTED"/>

    반응형

    댓글

Designed by Tistory.