定時任務服務器不定時重啟原因解析


現在定時任務服務存在問題,請幫忙核實一下:
 
現象:定時任務服務器的resin不定時重啟,有時能達到一天一兩次,原因是在創建單例bean時,單例bean正在被銷毀。報錯的類都是RunPickupPathService,每次重啟前都會報如下錯誤。 日志如下:
 
Caused by: org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'transactionManager': Singleton bean creation not allowed while the singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
 
[INFO]2014-08-15 15:46:27 INFO [resin-shutdown] org.springframework.scheduling.concurrent.ExecutorConfigurationSupport.shutdown(150) | Shutting down ExecutorService 'taskExecutor'
 
<!-- 定時檢查撿貨路徑不完整的, 是否有補貨進來, 如果補貨了,則重新跑撿貨路徑 -->
    <bean id="xsaCheckUnCompletePathIsSupplied" class="org.springframework.scheduling.quartz.CronTriggerBean">
       <property name="jobDetail">
            <ref bean="xsaCheckUnCompletePathIsSuppliedJobDetail"/>
       </property>
       <property name="cronExpression">
            <value>${checkUnCompletePathIsSuppliedCron}</value>
       </property>
    </bean>
    <bean id="xsaCheckUnCompletePathIsSuppliedJobDetail" class="springframework.scheduling.quartz.BeanInvokingJobDetailFactoryBean">
        <property name="targetBean" value="runPickupPathService" />
        <property name="targetMethod" value="checkUnCompletePathIsSupplied" />
    </bean>

    <!-- 對於所有沒有跑的撿貨路徑,進行跑撿貨路徑工作 -->
    <bean id="xsaRunUnRunPickupPath" class="org.springframework.scheduling.quartz.CronTriggerBean">
       <property name="jobDetail">
            <ref bean="xsaRunUnRunPickupPathJobDetail"/>
       </property>
       <property name="cronExpression">
            <value>${runUnRunPathCron}</value>
       </property>
    </bean>
    <bean id="xsaRunUnRunPickupPathJobDetail" class="springframework.scheduling.quartz.BeanInvokingJobDetailFactoryBean">
        <property name="targetBean" value="autoRunPickupPathService" />
        <property name="targetMethod" value="runAllUnRunPickupPath" />
    </bean>
 
這里targetBean autoRunPickupPathService 引用了如下的service,而 runPickupPathService 本身又是定時任務service,在跑完定時任務的時候需要被destory。
 
@Service
public class AutoRunPickupPathService {
    
    private final static Logger logger = LoggerFactory.getLogger(RunPickupPathService.class);
    @Resource
    private RunPickupPathService runPickupPathService;
    @Resource
    private XsaPickupPathMapper xsaPickupPathMapper;

    /**
     * 對於所有沒有跑撿貨路徑的單據,跑撿貨路徑, 此方法設置為定時
     * @throws Exception 
     */
    public void runAllUnRunPickupPath() {
        synchronized (RunPickupPathService.class) {
            List<XsaPickupPath> pathList = xsaPickupPathMapper.getAllUnRunPickUpPath();
            if(null != pathList && pathList.size() > 0) {
                for(XsaPickupPath p : pathList) {
                    try {
                        runPickupPathService.runPickupPath(p.getServiceno(), true);
                    } catch (Exception e) {
                        logger.error("Auto Run Pickup Path Error, Transfer NO: " + p.getServiceno() + ", " + e.getMessage());
                    }
                }
            }
        }
    }

}

 

出現這種情況是下面情形,按時間先后出現如下 1->2->3->4
 
1、autoRunPickupPathService 已經運行結束,當前時間只有runPickupPathService 在運行。
2、runPickupPathService 運行完畢,發現此時沒有別的類在引用自己,於是開始執行對bean的銷毀(由spring控制,調用destory方法,不集成spring則由GC回收)。
3、在 runPickupPathService 正在銷毀但銷毀未完成的時候定時任務 autoRunPickupPathService開始執行,由於類中引用了runPickupPathService ,於是開始創建runPickupPathService的實例。
4、由於spring的bean默認情況下都是單例(singleton),導致出現如上報錯,即 Singleton bean creation not allowed while the singletons of this factory are in destruction 。
 
最終解釋可以歸為一句話:定時任務的相互調用會導致單例bean出現混亂。
 
解決方案:去掉定時任務之間的調用
 
這是我分析的原因,我檢測的三次重啟都是由這個定時任務創建bean失敗導致。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM