2013-07-24 19 views
6

Tôi đang làm việc trên một ứng dụng đang sử dụng Spring 3, Hibernate và JPA. Tôi có hai lớp học như sau:Trình lập lịch trình mùa xuân - Khi có sự phụ thuộc theo chu kỳ, phương thức được lập biểu không bắt đầu trong giao dịch

@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 
    } 
} 

Phần liên quan từ bối cảnh ứng dụng như sau:

<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"/> 

Với cấu hình này, tôi nhận được ngoại lệ sau đây

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) 

Nếu tôi loại bỏ autowiring của lớp Manager từ lớp Util, nó hoạt động tốt. Ngoài ra, trong khi gỡ lỗi, tôi thấy rằng phương thức được lập lịch bắt đầu thực thi ngay cả khi có một số lỗi trong tệp ngữ cảnh ứng dụng.

Vì một số lý do trước đây, tôi không thể tránh sự phụ thuộc theo chu kỳ. Ai đó có thể giúp lý do tại sao ngoại lệ này xảy ra trong trường hợp phụ thuộc cyclic?

+0

Dường như quá trình lên kế hoạch postprocessor đậu trần ngay cả khi nó là nghĩa vụ phải bắn sau khi tác giả ủy quyền AOP (vì postprocessors được sắp xếp). Tôi nghĩ rằng bạn có thể gửi một lỗi đến Spring JIRA, ít nhất hành vi này kém tài liệu. Để giải quyết sự cố này, bạn có thể kích hoạt phương thức giao dịch từ một bean riêng biệt với phương thức được lập biểu hoặc sử dụng TransactionTemplate thay vào đó nếu giao dịch. –

Trả lời

0

Bạn có thể đạt được điều này bằng @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 
    } 
} 
Các vấn đề liên quan