Spring Scheduler任务

时间:2017-10-18 22:54:38

标签: java spring java-ee websphere

我们在Webshere Application Server上运行了一个EJB应用程序。部分处理有几个计划任务需要运行,修复延迟为50到200毫秒,所以我们不得不使用Spring计划任务来实现这一目标。

Spring应用程序上下文仅在应用程序使用javax.ejb.Singleton javax.ejb.Startup带注释的bean启动时加载一次:

@Singleton
@Startup
public class ApplicationLifeCyleBean {
    private ApplicationContext applicationContext;

    @PostConstruct
    public void initialize() {
        applicationContext = Application.CONTEXT.getApplicationContext();
    }
}

Application.CONTEXT只是作为枚举创建的单例,以确保它只加载一次。请注意,在WAS中只为此应用程序配置了一个类加载器。

public enum Application {
    CONTEXT;

    applicationContext = new ClassPathXmlApplicationContext("application-context.xml");

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

现在在application-context.xml内我们定义了我们的预定任务,如下所示:

<bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
    <property name="resourceRef" value="true"/>
    <property name="workManagerName" value="wm/default" />
</bean>

<bean id="taskScheduler" class="org.springframework.scheduling.commonj.TimerManagerTaskScheduler">
    <property name="resourceRef" value="true"/>
    <property name="timerManagerName" value="java:app/env/timerManager"/>
    <property name="shared" value="false"/>
</bean>

<bean id="myProcessor" class="my.company.MyProcessor"/>

<task:scheduled-tasks scheduler="taskScheduler">
    <task:scheduled ref="myProcessor" method="process" fixed-delay="${my.proc.interval}"/>
    ...
</task:scheduled-tasks>

这个处理器的作用是从数据库中删除一些过期的记录,我们发现日志中偶尔会出现一些死锁异常。我们唯一的解释是DELETE同时由多个进程执行。考虑到这一点,为了帮助我们进行调查,我们添加了一个额外的单例来存储运行状态,并更改了MyProcessor代码以记录运行状态,如下所示:

public enum Processors {
    MY_PROCESSOR;

    private boolean running;

    public synchronized boolean isRunning() {
        return running;
    }

    public synchronized void setRunning(boolean running) {
        this.running = running;
    }
}

public class MyProcessor {
    public void process () {
        if (Processors.MY_PROCESSOR.isRunning()) {
            logger.warn("My process was found to be running. Please investigate.");
        } else {
            Processors.MY_PROCESSOR.setRunning(true);
            // Do some work here  
            Processors.MY_PROCESSOR.setRunning(false); 
        }
    }
}

正如预期的那样,日志中有两个处理器运行实例:

[18/10/17 0:01:32:613 EST] 00000245 SystemOut     O    [WARN ] my.company.MyProcessor - My process was found to be running. Please investigate.
[18/10/17 0:03:32:626 EST] 00000244 SystemOut     O    [WARN ] my.company.MyProcessor - My process was found to be running. Please investigate.
[18/10/17 0:05:32:640 EST] 00000245 SystemOut     O    [WARN ] my.company.MyProcessor - My process was found to be running. Please investigate.
[18/10/17 0:07:32:654 EST] 00000245 SystemOut     O    [WARN ] my.company.MyProcessor - My process was found to be running. Please investigate.
[18/10/17 0:09:32:668 EST] 00000245 SystemOut     O    [WARN ] my.company.MyProcessor - My process was found to be running. Please investigate.
[18/10/17 0:11:32:682 EST] 00000245 SystemOut     O    [WARN ] my.company.MyProcessor - My process was found to be running. Please investigate.
[18/10/17 0:13:32:696 EST] 00000245 SystemOut     O    [WARN ] my.company.MyProcessor - My process was found to be running. Please investigate.
[18/10/17 0:15:32:710 EST] 00000244 SystemOut     O    [WARN ] my.company.MyProcessor - My process was found to be running. Please investigate.

现在我们不再获得死锁,但仍然存在导致创建两个实例的问题。

提前感谢您的意见/建议

0 个答案:

没有答案