스프링 AOP bean 주입시 트랜잭션 무시되는 문제 : Spring AOP Transaction ignore
반응형
스프링 AOP bean 주입시 트랜잭션 무시되는 문제 : Spring AOP Transaction ignore
서비스(빈)를 AOP에 주입하면 트랜잭션이 무시되는 문제가 있다. 어떻게 작업을 했는 지 아래의 소스를 보도록한다.
@Service
@Transactional
public class DemoService {
@Resource(name = "demoDAO") private DemoDAO demoDAO;
@Transactional(readOnly = true)
public List<Demo> getDemoList() {
return (List<Demo>) demoDAO.findAll();
}
public Demo saveDemo(Demo demo) {
return demoDAO.save(demo);
}
public void saveTest(Demo demo) {
saveTest(demo, false);
}
public void saveTest(Demo demo, boolean is) {
saveDemo(demo);
throw new RuntimeException(""); // 롤백을 위한 강제 익셉션
}
public void getTest() {
System.out.println("aop 요청.");
}
}
서비스 클래스를 만들었다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = BootstrapContext.class)
@ActiveProfiles({"dev", "jpa"})
public class TestDemo {
@Resource(name = "demoService") private DemoService demoService;
@Test
public void crud() {
Demo demo = new Demo("syaku", "제목", "내용");
demoService.saveTest(demo, false);
System.out.println(demoService.getDemoList().size());
}
}
테스트 클래스를 만들다. 위 소스는 실행하면 문제없이 롤백이 된다. 하지만 아래와 같이 DemoService 를 xml 스키마 기반으로 AOP를 설정하면 트랜잭션이 무시가 된다. 아래의 설정이 사용되며 선언적인 트랜잭션 설정이 무시되는 것 같다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<aop:config>
<aop:aspect id="demoServiceAOP" ref="demoService">
<aop:pointcut id="demoServiceAOPPointcut" expression="execution(* org.springframework.security.web.authentication.logout.LogoutHandler.*(..))" />
<aop:after pointcut-ref="demoServiceAOPPointcut" method="getTest" />
</aop:aspect>
</aop:config>
</beans>
단 Java기반 AOP 설정은 무시되지 않는 것 같다. 즉 아래와 같이 하면 문제가 되지 않는 다.
@Aspect
@Component
public class DemoServiceAOP {
@Resource(name = "demoService") DemoService demoService;
@Pointcut("execution(execution(* org.springframework.security.web.authentication.logout.LogoutHandler.*(..))")
private void demoServiceAOPPointcut() {}
@After("demoServiceAOPPointcut()")
public void getTest(JoinPoint thisJoinPoint) {
demoService.getTest();
}
}
xml 스키마 기반으로 AOP를 사용하려면 주입할때 demoService를 AOP용으로 새로만들어 사용하면 문제를 해결할 수 있다.
@Component
public class DemoAOPSupport {
@Resource(name = "demoService")
DemoService demoService;
public void getTest() {
demoService.getTest();
}
}
<aop:aspect id="demoServiceAOP" ref="demoAOPSupport">
이렇게 주입해주면 된다.
로그를 확인하기 위한 설정
<logger name="org.springframework.jdbc" level="debug" />
<logger name="org.springframework.aop" level="debug" />
반응형
'개발노트 > Spring' 카테고리의 다른 글
스프링 시큐리티 중복로그인 검사 : Spring security duplication login check (0) | 2016.10.10 |
---|---|
Spring security Concurrent Session Control, Remember Me : 스프링 시큐리티 중복로그인 , 로그인 기억 , 동시성세션제어 (0) | 2016.09.30 |
Spring Ehcache : 스프링 캐시 설정 (0) | 2016.07.28 |
스프링 빈 라이프사이클 : Spring Bean lifecycle (0) | 2016.03.25 |