Chinaunix首页 | 论坛 | 博客
  • 博客访问: 483062
  • 博文数量: 1496
  • 博客积分: 79800
  • 博客等级: 大将
  • 技术积分: 9940
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-09 13:22
文章分类

全部博文(1496)

文章存档

2011年(1)

2008年(1495)

我的朋友

分类:

2008-09-09 13:27:05


  先了解一下这几个特性,他们是:
  
  1)设定时间间隔后能重复定时的Timer
  
  在EJB 2.1规范中定义的Timer有两种,一种是single-event timers,另一种是interval timers。single-event timers在它的生命周期中只产生一次timeout,而interval timers可以在每经过一段时间间隔后产生一次timeout。
  
  2)Timer的持久性
  
  如果被关机,那么这些timer仍然起作用,等到下次启动时能够继续计时。假如启动时已经超时,那么立即产生timeout。
  
  3)事务特性
  
  Timer的创建(create)、取消(cancel),以及EJB的ejbTimeout方法都可以参与事务,作为事务的一部分,他们可以在事务回滚(Rollback)时恢复状态。
  
  也就是说,如果在事务中调用TimerService的createTimer方法,那么回滚时将销毁创建的Timer;如果在事务中调用了Timer的cancel方法,那么回滚时将恢复这个Timer。
  
  如果因为ejbTimeout方法运行失败导致事务回滚,那么规范要求服务器的Timer Service在之后要至少再次调用ejbTimeout方法一次。之所以要求这样做的原因呢,我想可能是因为那些需要定时完成的业务都是相对比较重要的,如果Rollback后不加以处理可能会产生严重后果。
  
  好了,现在开始我们的试验。不过对于timer service的基础知识,以及如何写一个使用timer service的EJB,我这里就不作详细介绍了,有需要的话可以看看以下的文章。http://sammi_tea.mblogger.cn/posts/10373.aspx
  
  一、准备
  
  因为Timer服务是EJB 2.1的特性,需要一个实现了EJB 2.1的服务器,我就了Apusic 4.0来测试。
  
  地址:
  
  二、试验方案
  
  对于上述的特性,我打算在同一个应用中测试,这个应用很简单,客户访问一个Jsp页面,激活 Timer,这个Timer在超时后会调用一个stateless session bean的ejbTimeout方法,此时我们就在后台打印出调试信息。
  
  需要说明的是,Stateful session bean 中不可以使用Timer Service,其他类型的EJB都可以。
  
  三、试验结果
  
  1)对于最常用的single-event timers,试验结果是正常的,服务器可以在计时超时的时候调用ejbTimeout方法。创建这种Timer的代码片断如下:
  
  public String getHello(){
  
  TimerService ts = sessionContext.getTimerService();
  
  ts.createTimer(20000, null); //计时20秒
  }
  
  2)对于interval timers类型,试验结果也是正常的,服务器可以在每次间隔时间超时的时候调用ejbTimeout方法。创建这种Timer的代码片断如下:
  
  public String getHello(){
  
  TimerService ts = sessionContext.getTimerService();
  
  ts.createTimer(new Date(第一次超时时间), 20000, null);
  }
  
  3)对于Timer的持久性,我采用重启服务器的方法,当服务器重新启动后,如果时间还没有超时,服务器会继续计时,这一点是正确的;另一种情况下,如果启动后时间已经超时,服务器会在启动后立即调用ejbTimeout,试验通过。
  
  4)针对三个方法的事务特性,我分别写代码来测试。首先,单独将createTimer方法包含在一个UserTransaction事务中,并在运行中将事务rollback。试验中,服务器将事务回滚,之后Timer不再起作用,没有调用ejbTimeout方法。代码如下:
  
  public String getHello(){
  
  UserTransaction tx = sessionContext.getUserTransaction();
  
  tx.begin();
  
  ts.createTimer(30000, null);
  
  tx.setRollbackOnly();
  
  tx.commit();
  
  }
  
  5)对于cancel方法的事务特性,和上面的过程类似,将Timer.cancel()包含在一个事务中,并在运行过程中将事务rollback。试验中,服务器将事务回滚,之后Timer可以继续计时,并调用ejbTimeout方法。代码如下:
  
  public String getHello(){
  
  Timer at = ts.createTimer(30000, null);
  
  UserTransaction tx = sessionContext.getUserTransaction();
  
  tx.begin();
  
  at.cancel();
  
  tx.setRollbackOnly();
  
  tx.commit();}
  
  }
  
  6)对于ejbTimeout方法的事务特性,试验时我把这个方法的CMT属性设置为RequiresNew,同时在此方法中模拟失败后调用rollback的情况,首先服务器把事务回滚,然后在5秒后再次调用ejbTimeout方法,完全和规范描述的一样。实际上这个5秒的时间是可以自己配置的,在apusic.conf文件中,有EJBTimerService的配置,内容如下:
  
  
  
  
  
  
  其中的RedeliveryInterval指的就是重新调用ejbTimeout的等待时间。而另一项MaxRedeliveries属性指的是重新调用的次数。
  
  我测试的代码如下:
  
  public void ejbTimeout(Timer timer){
  
  System.out.println("timer expired");
  
  sessionContext.setRollbackOnly();
  
  }
  
  四、结束语
  
  EJB 2.1中新增的EJB Timer Service功能虽然简单,但是它的一些高级特性却很实用,遗憾的是大家还没有注意到这些特性,我在这里抛砖引玉,做一个小小的测试,希望能对哪些对Timer服务感兴趣的人有帮助。以上所有特性都只在Apusic 4.0上进行了试验,全部通过测试。
【责编:admin】

--------------------next---------------------

阅读(97) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~