我在webapp中运行了一个Quartz计时器任务。 该任务每10秒检查一次数据库中是否存在特定表中的新数据。
<bean id="triggerCheckEvents" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<bean id="jobCheckEvents" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="checkEvents" />
<property name="targetMethod" value="execute" />
<property name="concurrent" value="false" />
</bean>
</property>
<property name="startDelay" value="${checkEvent.startDelay}" />
<property name="repeatInterval" value="${checkEvent.repeatDelay}" />
大约每隔一天左右,计时器停止运行。我有点肯定它在数据库中做某事时会卡住。但是,重新启动数据库似乎对恢复计时器的正常运行没有影响。没有异常被抛出。所以没有堆栈跟踪。
虽然我试图找到根本原因。我认为,I / O问题必然会在长时间运行的过程中发生。所以这个问题的正确解决方案就是拥有某种看门狗,比如说,在超时后杀死线程,产生一个新的步骤并按照计划继续计时器。
当任务在指定的时间范围内无法返回时,是否有办法终止计划任务并创建新实例?
我没有尝试使用数据库修复此特定错误。因为明天一些其他错误可能会阻止线程。我正在寻找一种高水平的解决方案,可以终止胎面或做任何事情 需要释放被挂起的计时器线程阻塞的资源 创建一个新的实例。长期以来意外的问题是不可避免的 运行过程。正确的解决方案不是研究和修复众多问题 个别问题,当他们出现时,但有一个策略 即使发生错误也能恢复正常功能。
答案 0 :(得分:2)
我遇到类似的问题,其中一项任务被阻止。一种方法是:在每次调用任务时,在新线程中执行实际操作并使任务的线程等待新线程完成(直到超过最大允许时间)。这样任务永远不会被阻止。
public void work(JobExecutionContext ctx) {
Thread t = new Thread(new Runnable() {
public void run() {
doSomethingInNewThread();
}
}, "ThreadName-" + System.currentTimeMillis());
t.start();
try {
t.join(maxAllowedTime);
if (t.isAlive()) {
logger.warn("Tasks child thread "
+ t.getName()
+ "is still alive, potential thread block.");
//TBD - if needed, add logic to terminate child thread
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}