Spring에서 트랜잭션 처리 시 @Transactional 어노테이션을 사용하면 rollback이 안된다.
이와 같은 오류로 어려움을 겪고 있다면 아래 해결 방법들을 이용해 보도록하자.
1. mysql 데이터베이스를 사용할경우 테이블 타입 확인
mysql은 테이블타입이 InnoDB일 때만 트랜잭션이 동작한다고 한다. 테이블 타입을 확인해보고 InnoDB로 변경해준다.
2. 인터페이스 코드 유무 확인
트랜잭션을 이용할 클래스들이 인터페이스를 사용하는지 확인해봐야 한다.
@Transactional 어노테이션 같은 경우 Spring AOP를 이용하게 되는데 이 AOP는 기본적으로 Dynamic Proxy를 이용한다.
Dynamic Proxy는 인터페이스 기반으로 동작하기 때문에 인터페이스가 없을경우 트랜잭션이 동작하지 않는다.
인터페이스 없이 트랜잭션 동작하게 하려면 CGLib(Code Generation Library) Proxy를 이용하면 된다.
CGLib Proxy는 클래스에 대한 Proxy가 가능하기 때문에 인터페이스가 없어도 된다.
CGLib Proxy를 이용하는 방법은 다음과 같다.
1) maven에 cglib 추가
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
2) servlet context에 proxy-target-class 속성 추가
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<tx:annotation-driven proxy-target-class="true"/>
......
</beans:beans>
※ 만일 cglib 라이브러리를 추가 안하고 proxy-target-class 속성을 이용하게 되면 아래와 같은 오류메시지가 나타난다
Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces. |
3. application context 설정 파일에 transaction 관련 설정있는지 확인
DB설정 부분 application context 쪽에 할 경우, 이 DB설정은 servlet context쪽에 설정된 Bean들에는 적용이 안된다.
그래서 transaction관련 설정을 servlet context에 해줘야한다.
아래 구문이 application context에 있다면 servlet context 로 옮겨준다.
<tx:annotation-driven proxy-target-class="true"/>
'Java > spring' 카테고리의 다른 글
Spring에서 Json으로의 입출력 정리 (1) | 2014.05.17 |
---|---|
Spring Framework와 [IOC / DL / DI] 정의 (0) | 2013.09.12 |
@Configuration과 @Bean을 이용한 Spring Framework 환경 설정의 Java 코드화 (0) | 2013.07.25 |