服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

ejb timer service的高级特性心得分享

  
  ejb 2.1中新增了一个timer service服务,我也看到一些文章介绍如何使用timer服务,但是关于timer服务的几个重要特性就言之甚少。我看了ejb 2.1规范后又试验了一下这些相对比较高级的特性,介绍给大家共享。

  先了解一下这几个特性,他们是:

  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来测试。

  下载地址:http://www.apusic.com

二、试验方案

  对于上述的特性,我打算在同一个应用中测试,这个应用很简单,客户访问一个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的配置,内容如下:

  <service class="com.apusic.ejb.timer.ejbtimerservice">
  <attribute name="redeliveryinterval" value="5000"/>
  <attribute name="maxredeliveries" value="1"/>
  </service>

  其中的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上进行了试验,全部通过测试。本来还想在weblogic 9.0 beta上也做相同的测试,但是我拿到的版本总是不能顺利的部署j2ee 1.4的应用,无奈只好放弃,还请有兴趣的朋友做进一步测试。

扫描关注微信公众号