2011-09-02 1 views
0

저는 선언적 트랜잭션 관리 기능이있는 Spring + Hibernate 어플리케이션을 보유하고 있습니다. 2 개의 공개 메소드 MethodAMethodB을 가진 서비스 (FooService)가 있습니다. 클라이언트는 callMethodA을 차례로 호출하여 MethodB을 호출합니다.Spring에서의 선언적 트랜잭션 관리는 예측할 수 없게 동작합니다.

Client -> MethodA -> MethodB 

트랜잭션을 MethodB부터 시작하고자합니다. 이 내 스프링 애플리케이션 컨텍스트에서 코드 조각입니다 : 내 클라이언트에서 MethodA를 호출 할 때 MethodB 호출 할 때

<bean id="FooService" 
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager" ref="transactionManager" /> 
    <property name="target" ref="FooServiceTarget" /> 
    <property name="transactionAttributes"> 
     <props> 
     <prop key="MethodB">PROPAGATION_REQUIRED,-FooException</prop> 
     </props> 
    </property> 
</bean> 

는 그러나, 트랜잭션 프록시를 만들지 않습니다. 응용 프로그램 컨텍스트의 빈 구성에 MethodA을 추가하면 트랜잭션 프록시가 호출됩니다 (예상대로 MethodA으로 시작). 왜 이렇게됩니까? MethodB 이후에서만 생성되는 트랜잭션을 얻을 수 있습니까?

답변

2

클라이언트 -> MethodA -> MethodB

내가 트랜잭션이 이후

이 작동하지 않을 수 MethodB에서만 시작하려는. 메소드 A와 메소드 B는 동일한 프록시 내에 있습니다.

유일한 방법은 메소드 B를 다른 Bean으로 이동하는 것입니다.

BTW :

+0

답변 해 주셔서 감사합니다.죄송합니다. 나는이 질문들이 이미 SO에 관한 질문을 받았음을 알지 못했습니다. –

2

내가되는 트랜잭션을 달성 할 수있다 :이 요청 된 많은 시간 전에, 여기 내 일부 이전 답변입니다 MethodB 이후에서만 생성됩니까?

use AspectJ bytecode weaving with Spring 인 경우에만.

왜 이렇게 되나요?

스프링의 기본 AOP 메커니즘은 서비스 인터페이스를 구현하는 별도의 프록시 인스턴스를 만드는 JDK dynamic proxies입니다. 이 프록시는 서비스 대신 다른 Bean에 주입되며이를 통해 전달되는 모든 호출은 서비스 위임 전에 트랜잭션 작업을 수행합니다. 서비스에서 자체 호출로 프록시를 거치지 않으므로 트랜잭션을 시작할 수 없거나 시작되지 않습니다. AspectJ 바이트 코드 제직을 사용하면 트랜잭션 코드가 직접 서비스에 포함되어 제대로 작동합니다. 하지만이 목적을 위해 필요하다면, "서비스"를 적어도 두 개의 분리 된 객체로 리팩터링해야 할 때가 있습니다. 왜냐하면 그것은 관심사 및/또는 교차 추상화 레이어가 혼합 된 신호이기 때문입니다. 하나의 클래스.