我创建了EJB 3 Timer,并将其部署到weblogic集群中。 createTimer参数是createTimer(1000,20000,null); 这应该每20秒创建一个重复计时器。但是计时器总是每30秒创建一次。我甚至将intervalDuration更改为40和50秒,但是超时方法总是每30秒触发一次。
以下是WEBLOGIC_TIMERS表的条目 1 @@ OSBNode2_1355845459844(BLOB)1355846770914 1000 TimerearTimerTest.jarTimerTest OSBDomain OSBCluster
以下是ACTIVE表中的条目 timer.1 @@ OSBNode2_1355843156331 -96726833478167425 / OSBNode2 OSBDomain OSBCluster 18-DEC-12 service.TimerMaster 8866906753834651127 / OSBNode1 OSBDomain OSBCluster 18-DEC-12 service.SINGLETON_MASTER 8866906753834651127 / OSBNode1 OSBDomain OSBCluster 18-DEC-12
任何人都可以帮我调查为什么计时器总是每30秒触发一次而不是我的intervalDuration值?
以下是EJB ----->>
package com.timertest;
import java.util.*;
import javax.annotation.Resource;
import javax.ejb.*;
@Stateless(mappedName = "TimerTest")
public class TimerTest implements TimerTestRemote
{
@Resource
private SessionContext ctx;
@Override
public void createMyTimer()
throws EJBException
{
ctx.getTimerService().createTimer(1000, 20000, null);
}
@Timeout
public void timeout(Timer timer)
{
System.out.println("-> Timed Out ..."+ new Date());
}
}
Below is the and weblogic descripor-------->>
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-ejb-jar
xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd http://xmlns.oracle.com/weblogic/weblogic-ejb-jar http://xmlns.oracle.com/weblogic/weblogic-ejb-jar/1.2/weblogic-ejb-jar.xsd">
<wls:weblogic-enterprise-bean>
<wls:ejb-name>TimerTest</wls:ejb-name>
<wls:stateless-session-descriptor>
<wls:stateless-clustering>
<wls:home-is-clusterable>true</wls:home-is-clusterable>
<wls:home-load-algorithm>round-robin</wls:home-load-algorithm>
<wls:stateless-bean-is-clusterable>true</wls:stateless-bean-is-clusterable>
<wls:stateless-bean-load-algorithm>round-robin
</wls:stateless-bean-load-algorithm>
</wls:stateless-clustering>
<wls:business-interface-jndi-name-map>
<wls:business-remote>TimerTestRemote</wls:business-remote>
<wls:jndi-name>TimerTest</wls:jndi-name>
</wls:business-interface-jndi-name-map>
</wls:stateless-session-descriptor>
<wls:enable-call-by-reference>false</wls:enable-call-by-reference>
<wls:jndi-name>TimerTest</wls:jndi-name>
</wls:weblogic-enterprise-bean>
<wls:timer-implementation>Clustered</wls:timer-implementation>
</wls:weblogic-ejb-jar>
提前致谢
答案 0 :(得分:0)
这可能不是直接的答案,但可能有助于避免这种情况。
默认情况下,计时器是持久的,因此您必须在开始新计时器之前取消之前的计时器。
此外,您可以在创建计时器对象时提供info
而不是传递null
,可以是字符串标识符。稍后它将有助于确定哪个计时器已超时或在系统中有多个计时器时取消它。
创建计时器&amp;多次重启应用程序,有几个这样的计时器具有相同的info
,但具有不同的hashCode
。所以他们不重叠&amp;每次都是新建的。
您可以通过ctx.getTimerService().getTimers()
&amp;通过迭代来取消。
修改:我已复制了该方案&amp;面临类似的问题。我调试了&amp;如果多个先前的计时器在同一时间间隔内有效,则会发生这种情况,这些时间表未被取消。
你尝试下面的代码,我试过&amp;它解决了这个问题。
for(Timer t : timerService.getTimers())
t.cancel(); //-- Cancel timers before creatimng new one
ctx.getTimerService().createTimer(1000, 20000, null);
文件摘录:
intervalDuration - 如果到期时间延迟(例如由于bean上其他方法调用的交错),可能会在接近“赶上”的情况下发生两个或更多到期通知。
答案 1 :(得分:0)
您可以使用其他样式(注释)。见下文:
@Schedule(hour = "*", minute = "*",second = "*/40")
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@Lock(LockType.WRITE)
@AccessTimeout(1000 * 60 * 60)//1 Hour...//Concurrent Access is not permitted...