2013-07-24 4 views
6

Spring 3, Hibernate 및 JPA를 사용하는 응용 프로그램에서 작업하고 있습니다. 다음 나는 두 개의 클래스가 있습니다Spring Scheduler - 주기적 종속성이있는 경우 트랜잭션에서 예약 된 메소드가 시작되지 않습니다.

@Component 
class Manager { 
    @Autowired 
    Util util; 
} 

@Component 
class Util { 
    @Autowired 
    Manager manager; 

    @Scheduled(fixedDelay = 1 * 60 * 1000) 
    @Transactional(propagation = Propagation.REQUIRED) 
    public void scheduledMethod(){ 
     // Need to update the database in a transaction 
    } 
} 

을 다음과 같이 응용 프로그램 컨텍스트에서 관련 부분은 다음과 같습니다이 구성

<context:component-scan base-package="packageName" /> 
    <tx:annotation-driven /> 
    <bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="defaultPU" /> 
     <property name="dataSource" ref="dataSource" /> 
    </bean> 
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    </bean> 
    <task:annotation-driven executor="executor" scheduler="scheduler"/> 
    <task:executor id="executor" 
     pool-size="10" 
     queue-capacity="10000" 
     rejection-policy="CALLER_RUNS"/> 
    <task:scheduler id="scheduler" pool-size="10"/> 

, 나는 다음과 같은 예외가

javax.persistence.TransactionRequiredException: no transaction is in progress 
     at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:978) 
     at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365) 
     at com.sun.proxy.$Proxy43.flush(Unknown Source) 
     at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240) 
     at com.sun.proxy.$Proxy43.flush(Unknown Source) 

Util 클래스에서 Manager 클래스의 autowiring을 제거하면 올바르게 작동합니다. 또한 디버깅하는 동안 응용 프로그램 컨텍스트 파일에 오류가 있어도 예약 된 메서드가 실행되기 시작한다는 것을 알았습니다.

일부 레거시 이유로 인해 순환 종속성을 피할 수 없습니다. 주기적 종속성의 경우에이 예외가 발생하는 이유를 다른 사람이 도울 수 있습니까?

+0

에게 achive 수 있습니다 그것은 보인다 예약 후 처리 공정이 (후 - 처리 순서 때문에) AOP 프록시 생성자 후 해고 해야하는 경우에도 베어 콩. Spring JIRA에 버그를 보낼 수 있다고 생각합니다. 적어도이 동작은 문서화가 잘되어 있지 않습니다. 이 문제를 해결하려면 예약 된 메서드를 사용하여 별도의 빈에서 트랜잭션 방식을 실행하거나 트랜잭션 방식 인 경우 TransactionTemplate을 사용할 수 있습니다. –

답변

0

당신이 사용하는 @PostConstruct

@Component 
class Manager { 

    Util util; 

    public void setUtil(Util util) { 
     this.util = util; 
    } 
} 


@Component 
class Util { 
    @Autowired 
    Manager manager; 

    @PostConstruct 
    public void init(){ 
     manager.setUtil(this); 

    } 

    @Scheduled(fixedDelay = 1 * 60 * 1000) 
    @Transactional(propagation = Propagation.REQUIRED) 
    public void scheduledMethod(){ 
     // Need to update the database in a transaction 
    } 
}