我们在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.
现在我们不再获得死锁,但仍然存在导致创建两个实例的问题。
提前感谢您的意见/建议