2012-05-29 개발일지

오늘은 트랜잭션 설정과 롤백테스트를 해봤다.

아래 세개 사이트에서 지식을 참고하고 진행했다.

우선 DisPatcherServlet에 아래와 같은 트랜잭션에 관련 설정을 추가했다.

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

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

그리고 DAO단(persistence layer)단을 호출하는 Service단의 메서드에 @Transactional 어노테이션을 붙였다.

@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public void add(Temp temp) {
    try{
        tempDao.test();
        tempDao.test2();
    }catch(Exception e) {
        throw new RuntimeException();
    }
}

@Transactional속성으로 propagation과 readOnly를 추가했다. 트랜잭션 전파속성과 읽기속성에 관한 설정이다.

그리고 중요한 부분은 DAO단의 예외로 인해 Exception을 던졌을 때, add메서드에서 언체크예외로 던졌다는 것이다.

체크예외로 하지 않고 언체크예외로 던지게 되면 add메서드를 호출한 메서드도 따로 예외처리를 하지 않아도 되고,

가장 중요한건, 예외상황이 벌어졌을시 “롤백처리”가 가능하다는 점이다.

실제로 체크예외로 예외를 던진 결과 롤백처리가 되지 않았다. 이와 관련된 부분은 위의 링크에 포함되어 있다.

선언적 트랜잭션 관리를 위한 스프링의 기본적인 행동은 EJB convention을 따른다
즉, 롤백은 자동으로 언체크예외에서만 작동한다.

라는 점이다. 이 부분이 이번 테스트에서 건진 제일 큰 놈이다.

그리고, 테스트하면서 들었던 하나의 의문은 트랜잭션 관련 설정을 DispatcherServlet에

매핑되어 있는 xml안에 해야 트랜잭션이 적용된다는 것이다.

ContextLoaderListener의 xml에 트랜잭션 관련 설정을 넣어놓으면 트랜잭션이

적용되질 않았다. 아래 링크를 보면 DispatcherServlet과 ContextLoaderListener 각각

별도의 WebApplicationContext를 생성한다고 나오는데, 왜 ContextLoaderListener안에

트랜잭션관련 설정을 했을 땐, 트랜잭션이 적용되지 않는지 의문이다.

아~ 범균님 스프링 책을 다시 봐야겠다.

================================================================

트랜잭션이 적용되지 않는 문제는 오늘 기선님께 물어봐서 해결했다.

결국 아래 빈을 스캔하는 구문이 문제였다.

<context:component-scan base-package="com.test.*" />

저렇게 되면 트랜잭션이 적용되지 않는 Service와 Repository를 사용하게 되버려서 문제가 생긴다.

결국엔 DS와 CCL간의 컴포넌트 스캔을 다르게 설정해서 해결했다.

[DispatcherServlet]

<context:component-scan base-package="com.test.*">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>

[ContextLoaderListener]

<context:component-scan base-package="com.test.*">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

결국엔, 트랜잭션 설정이 있는 CCL쪽에선 Controller를 제외한 Service, Repository의 빈을 등록하고

DS에선 Service, Repository의 빈을 제외한 Controller빈을 등록해서 중복을 제거함으로서 문제를 해결했다^^ 아래 포스팅을 참고하자

Advertisements

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중