C,C#,JAVA,JSP,SPRING,PYTHON,IOT

Header Ads

2014/06/11

@Transactional spring 롤백 트랜잭션

7 comments
트랜잭션 처리 부분을 만들려고 오전부터 머리를 좀 쎄게 굴려봤다.
알고나면 별 것 아닌 것들이... 할 때는 왜이렇게 사람을 힘들게 하는가...ㅎㅎ
여튼 예전에도 스프링에서 트랜잭션 처리를 해본적은 있었으나...
그 때 트랜잭션 처리는 좀 원초적인 느낌이 들었달까...
method마다 try-catch 문으로 감싸서 commit이나 rollback을 시켜주는 방식이었다.
트랜잭션 처리 할 부분이 많지는 않았지만... 반복적인 코드가 많이 늘어난다는 사실...
그래서 책보다가 선언적 트랜잭션 처리를 보았다.
대충 읽어보니 매우 간단해 보이는 느낌...
@Transactional 만 넣어주면 알아서 트랜잭션 처리가 되는듯한...?
이 설정을 위해서 mybatis설정 xml 파일인 mybatis-context.xml에 아래 태그를 추가했다.
    
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     <property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

<!--
해당 xml이 tx를 인식하지 못한다면...  아래 굵게 표시 된 부분이 없어서 그러니 추가...
-->
그리고 service 클래스에서 강세로 exception을 발생시켜보았지만... 트랜잭션 처리는 개뿔 되지 않았다.
열심히 인터넷을 뒤졌다. 사실 영어도 모르고 실력도 없는 내 입장에서 방법은 하나다.
기초적인거라도 인터넷에서 이렇게 저렇게 다 따라해보는 것... 설령 이렇게는 되지 않을 것 같다는 생각이 있는 소스들도
한 번을 따라해 볼 필요가 있다.
그렇게 몇 번을 하다보면... 대략 어떻게 돌아가는 것인지 조금은 파악이 되니까...
일단 처음 찾은 문제는...

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

위의 부분을 servlet-context.xml로 옮겨 주는 것이었다.
아마도 빈을 등록 할 때 트랜잭션에 대한 뭔가가 필요하기 때문일듯싶다.
사실 설정하는 부분이 어려운 것이... 제대로 처리가 되지 않으면 어디가 문제인지 알길이 막막하다는 것...
위의 부분을 수정한 뒤에 다시 트랜잭션 테스트를 해보았지만... 트랜잭션을 먹히지 않았다.
이렇게 되면...

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

이 태그 자체가 필요한 것인지... 아닌 것인지 자체도 의심스러워지는 상황...
또 한 참을 헤메고 여기저기 보다가 이클립스화면에서 뭔가 발견했다.
servlet-context.xml

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

태그를 추가하니...코드의 line number가 있는 곳에 휘어진 양방향 화살표가 표시 되는 것이었다.
마우스를 올려보니... 안내문구가 영어로 떴다.
영어로 표시 됐지만... 트랜잭션이란 단어는 느낌 아니까...
아... 여기에 추가하는 것이 맞긴 맞구나... 깨닫고 다른 문제가 뭔지 찾기 시작했다.
그 다음으로 테스트를 통해 찾은 문제는...
Exception을 강제 발생시키니... 트랜잭션 처리가 되지 않았는데...
소스 자체에 문제가 있어서 발생 된 exception에서는 트랜잭션 처리가 되는 것이다.
이건 왜일까...
트랜잭션 전파에 대해서 생각하게 됐다.

혹시 메소드에 @Transactional 게만 설정하면... 해당 메소드 내의 오류만 트랜잭션 처리가 되는 것인가? 그 안에서 다른 객체를 생성하서 쓰거나 다른 메소드를 호출해서 난 Exception은 트랜잭션 처리가 되지 않는것일까...?
그래서 @Transactional 에 추가되는 옵션을 보았다.

@Transactional(propagation = Propagation.REQUIRED)

이런게 있었다.
REQUIRED는 기존에 트랜잭션이 있는 상태면 기존 것을 따라가고 없다면 새로운 트랜잭션을 실행한다는 의미?

@Transactional(propagation = Propagation.REQUIRED, rollbackFor={Exception.class})
rollbackFor={Exception.class}

이런 옵션도 있는데... 이것은 어떤 Exception이 발생했을 때 롤백처리를 할 것 인가...였다.

문제는 바로 rollbackFor={Exception.class}였다.
물론 그 이전에 servlet의 tx 태그 추가해주는 것도 있었지만....
강제로 Exception을 발생 시키면... 이것은 트랜잭션 처리를 못하나보다.
이렇게 강제 처리를 할 때는 명시적으로 rollbackFor={Exception.class} 이렇게 어떤 Exception 옵션처리를 해주어야만 트랜잭션 처리를 하나보다.
별것도 아닌데... 오전부터 밥먹고 나서까지 계속 찾아야 했네...

그래도 다행이다. 해결돼서...ㅋㅋ

댓글 7개:

  1. 트렌젝션 안먹어서 이틀동안 삽질 했는데 이글 보고 해결하고 갑니다

    <tx:annotation-driven ... 부분을 서블릿 xml에 넣으니까 되네요 ㅡ,.ㅡ;;

    감사합니다~ ㅋㅋ

    답글삭제
  2. 저도 고생하다가 겨우 해결했네요. 정말 감사합니다.

    답글삭제
  3. 저도 이글 보고 해결했어요!! 감사합니다.

    답글삭제
  4. 덕분에 큰 도움 됐습니다 감사합니당

    답글삭제
  5. Borgata Poker Room | Play at the best poker room in New Jersey
    Borgata Poker Room, Borgata's poker room. Borgata Poker Room in 윈벳 Atlantic City. 벳 365 주소 See sbobet all poker room 저녁 메뉴 추천 룰렛 action, 룰렛 배팅 including tournaments,

    답글삭제