以下的statelessbean部署后,用一个java客户端调用其中的startTimeService方法,启动定时器后,ejb容器在两次调用了Timeout方法后清除计时器(第一次调用后抛出EJBException,服务器设置了再调用多次超时方法后再清除计时器):
@Stateless
public class StatelessSessionBean implements StatelessSessionBeanRemote {
    @Resource
    TimerService timeService;
    
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void startTimeService() {
        timeService.createTimer(0, 1000, null);
    }
    
    @Timeout
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void timeout(Timer timer) {
        throw new EJBException();
    } 
}
EJB5018: 在 [categorySessionBean] 上调用 EJB 时抛出异常
javax.ejb.EJBException
        at business.categorySessionBean.timeout(StatelessSessionBean .java:79)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        ....
 EJB5018: 在 [categorySessionBean] 上调用 EJB 时抛出异常
javax.ejb.EJBException
        at business.categorySessionBean.timeout(StatelessSessionBean .java:79)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        ....
 EJB5119:[2] 传送失败后正在清除计时器 ['2@@1265684944562@@server@@domain1' 'TimedObject = StatelessSessionBean ' 'Application = EJBModuleTest' 'BEING_DELIVERED' 'PERIODIC' 'Container ID = 82947932293103618' 'Tue Feb 09 11:10:11 CST 2010' '2000' ]但如果StatelessSessionBean 改为这样,则ejb容器不会自动清除计时器,只是每次调用Timeout方法都抛出EJBException而已:@Stateless
public class StatelessSessionBean implements StatelessSessionBeanRemote {
    @Resource
    TimerService timeService;
    int i=0;
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void startTimeService() {
        timeService.createTimer(0, 1000, null);
    }
    
    @Timeout
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void timeout(Timer timer) {
        if(i==1){i=0;throw new EJBException();}
        else{i++;}    } 
}请问有谁可以解释一下是为什么呢?而且无论是把startTimeService还是timeout方法的TransactionAttributeType改为REQUIRES_NEW都不影响结果,请问TransactionAttributeType对定时器的创建和timeout方法的调用有什么影响?

解决方案 »

  1.   

     public void timeout(Timer timer) {
            if(i==1){i=0;throw new EJBException();}
            else{i++;}    } 根据上面这个代码,这个timeout方法每隔一秒会被容器调用一次。 第一次调用时i=0, 方法正常执行。第二次调用时i=1, 方法把i变成1再甩出异常。这时容器会retry(因为有异常),这时i=0, 方法正常执行.于是就这样一直异常,正常的执行下去了。
      

  2.   

    抛出了异常后,不是应该再调用多次timeout方法就会清除定时器了吗?不管再调用timeout方法时会否再抛出异常。是在glassfish v2里部署的,默认设置时抛出了ejbException后,再调用多次timeout方法就自动清除定时器。