Spring AOP를 사용하여 DB 트랜잭션시 주의점

프로그래밍/Spring MVC 2013. 8. 19. 12:49

Spring AOP를 사용하여 DB 트랜잭션시 주의점 

 

Spring AOP 를 통해 DB 트랜잭션을 관리하려던 중에 크나큰 벽을 만났다.  

트랜잭션을 위해 Spring AOP 설정 파일도 추가했고 DB 입출력시 별다른 오류가 발생하지 않아 당연히 DB 트랜잭션 처리가 되고 있는줄 알았었는데... 트랜잭션이 전혀 적용되지 않았다... 심각한 문제였다. Framework 전체의 구조를 변경해야 할지도 몰랐다.

 

Framework의 구조가 메인 Controller 에 Service(DB 입출 담당) 가 주입되어 해당 입출력을 처리하는 패턴으로 되어 있었다.

그리고 각 Service 는 BaseService 를 상속받기 때문에 Controller 단에서는 BaseService 에 구현되어 있는 입출력 메소드만 신경쓰면 됬는데 문제는 Spring AOP를 통해 DB 트랜잭션이 적용된 Service 클래스에 대한 Proxy 때문이다.

Spring AOP 에서는 DB 트랜잭션을 가능하도록 하기 위해 AOP 를 통해 객체에 대한 Proxy를 생성하여 트랜잭션을 관리한다.

Spring AOP 에 대한 자세한 사항은 Spring AOP 관련 문서를 참조하시길.

 

Spring AOP 에서는 CGLIB 를 사용하여 객체에 대한 Proxy를 생성한다. 

★ 그런데 CGLIB 가 생성한 트랜잭션이 적용된 Proxy는 오직 원래 클래스로만 주입되었을 경우 사용할 수 있다.

무슨 말인가 하면 Framework 구조상 Controller에서는 모든 Service 객체의 부모 클래스인 BaseService 를 사용하여 입출력을 사용한다.

만약 UserService 에 대한 DB 입출력을 처리하려고 할때 Controller 는 주입된 UserService 를 BaseService 로 캐스팅하여 사용하게 된다. ★ 하지만 CGLIB가 생성한 Proxy는 UserService 래핑처리한 Proxy 일 뿐이며 BaseService 클래스를 상속받지 않는다. 따라서 CGLIB가 생성한 트랜잭션이 적용된 Proxy는 Controller에 주입될 수 없다. 두둥~~~

 

이걸 알아내는데 2주 정도 걸렸다. ;;;

 

그럼 트랜잭션을 적용하기 위해서는 Framework 구조를 변경해야 하나? Framework 구조를 변경하는건 상당히 힘든 부분이다. 시간적으로나 안전성 때문에라도... 

우선은 Controller 메소드에 트랜잭션을 걸어 간단하게나마 해결은 했지만 근본적인 해결이 필요하다.

 

관련 Article

http://stackoverflow.com/questions/3852564/abstract-dao-pattern-and-springs-proxy-cannot-be-cast-to-problem


'프로그래밍 > Spring MVC' 카테고리의 다른 글

@ResponseBody 이해하기  (3) 2013.09.04
ContentNegotiatingViewResolver 이해하기  (0) 2013.09.04
Spring MVC - fileupload  (0) 2009.12.24
Spring MVC - Themes  (0) 2009.12.23
Spring MVC - Locale  (0) 2009.12.23
: