EJB3 CORE规范(第十八章)Timer服务

1         Timer服务
本章描述容器管理的Timer服务。这个服务可以让bean提供者注册在特定时间点、在特定时间之后和在一段之后回调的EJB。
1.1    概述
基于工作流的企业应用为了管理语义状态转换,这些转换通常由偶然发生的临时事件触发。
EJB Timer服务是容器管理的服务,它提供允许基于时间事件的调度回调方法。容器为这些时间事件提供可靠和事务性的服务。可以在特定的时间、特定的时间段、或者循环时间片来触发计时器调度通知。
Timer服务有EJB容器实现。企业bean通过EJBContext或者通过查找JNDI命名空间来进行依赖注入。
EJB Timer服务粗粒度的时间通知服务,它的目的是用于应用级处理模型,不是用于实时事件模型。
然而,用毫秒单位来表示时间,这是因为毫秒是Java SE平台API的最小单位。所以时间事件最好是对应于小时、天、或较长期间的时间事件。
下面的章节描述Timer服务充当不同EJB角色。
1.2    Bean提供者眼中的Timer服务
容器提供的EJB Timer服务允许企业bean注册在特定的时间、时间段或时间段之后发生的时间回调方法。计时器服务提供了创建和取消计时器的方法,也提供了定位和bean关联的计时器的方法。
计时器用于调度基于时间的回调。使用计时器服务的企业bean必须提供超时回调方法。这个方法可以是用Timeout注释符注释的方法,也可以是实现了javax.ejb.TimedObject接口的bean。Javax.ejb.TimedObject接口只有一个计时器回调方法ejbTimeout。可以为无状态会话bean、消息驱动bean和2.1实体bean创建计时器。不能为有状态会话bean创建(注:可能在将来的规范中增加这项功能)或者EJB3.0实体。
为2.1实体bean创建的计时器和实体bean的唯一标识建立关联。可以调用处于池化状态的任何bean实例的为无状态会话bean活消息驱动bean创建的计时器的超时回调方法。
当在创建计时器时指定的时间到达时,容器调用bean的超时回调方法。bean可以在到期之前取消计时器。如果计时器被取消,则不会调用回调方法(注:在竞态条件下的事件中,可能发生对超时回调方法的无关调用)。通过计时器的cancel方法来取消计时器。
通常在一个事务内调用计时器的创建和取消方法,以及超时回调方法。
计时器服务目的用于长业务流程模型。企业bean上的计时器在容器停止、服务器停止和企业bean激活/钝化以及加载/存储的声明周期过程中始终存在。
1.2.1    Timer服务接口
可以通过EJBContext接口的getTimerService方法或者通过lookup JNDI命名空间来注入Timer服务。TimerService接口有下列的方法:
public interface javax.ejb.TimerService {
public Timer createTimer(long duration,java.io.Serializable info);
public Timer createTimer(long initialDuration,long intervalDuration, java.io.Serializable info);
public Timer createTimer(java.util.Date expiration,java.io.Serializable info);
public Timer createTimer(java.util.Date initialExpiration,long intervalDuration, java.io.Serializable info);
public Collection getTimers();
}
计时器的创建方法允许计时器作为一个单独时间的计时器或者作为一个时间段计时器。计时器终止时间(在时间段计时器情况下,需要初始话终止时间)可以是持续时间(时间段)也可以是绝对时间。
Bean可以在创建计时器时传入特定的客户信息来识别计时器到期的含义。这些信息由计时器服务存储并可以通过计时器获得。信息对象必须是可序列化的(目前,除了通过createTimer方法外没有其他方式可以来创建信息对象。在将来的版本中可能会增加一个API来创建信息对象)。
计时器持续时间以毫秒的方式来表达。计时器服务从计时器被创建时来计算计时器的持续时间。
createTimer方法返回一个Timer对象,这个对象可以允许企业bean取消计时器或者在计时器取消或/和到期之前获得计时器的信息(如果是一个单事件的计时器)。
getTimers方法返回和bean关联活动的所有计时器。对于EJB2.1实体bean,getTimers的结果是和实体bean唯一标识关联的所有计时器。
1.2.2    超时回调
注册到计时器服务的企业bean的class必须提供超时回调方法。
这个方法可以是由Timeout注释符注释的方法(或者在部署时指定一个方法作为一个超时方法)或者这个bean实现javax.ejb.TimedObject接口。这个接口只有一个方法就是ejbTimeout。如果bean实现了TimedObject接口,那么Timeout注释符或timeout-method只能用于指定ejbTimeout方法。一个bean最多只能有一个超时方法(注:这个方可以指定在bean的class上或者在它的超类上。如果使用Timeout注释符或bean实现TimedObject接口,那么如果指定timeout-method元素,则这个元素必须指向同一个方法)。
public interface javax.ejb.TimedObject {
public void ejbTimeout(Timer timer);
}
任何注释为Timeout的方法(或者在配置描述符中指派)都必须有是下面的形式,其中<METHOD>是方法的名字(注:如果bean实现了TimedObject接口,在ejbTimeout方法上可以也可以不使用Timeout注释符)。Timeout方法可以是public,private,protected,或者package级别。Timeout方法不能是final或static的。
void <METHOD>(Timer timer)
超时回调方法不能抛出应用异常。
当计时器到期时(例如,在创建时指定的毫秒数到期或超过指定的绝对时间),容器调用bean的为计时器注册的超时回调方法。超时方法包含bean提供者用于处理超时事件的业务逻辑。当计时器到期时,容器调用这个超时方法。当计时器被创建时,Bean提供者可以使用getInfo方法来获取计时器提供的信息。这些信息使得受时间管理的对象能够识别计时器到期的含义。
容器交叉调用业务方法、生命周期回调方法和超时回调方法。因此,超时回调方法被调用的时间点可以和创建计时器时指定的时间不完全一致。如果一个bean上有多个计时器并且他们几乎在同一时间到期,那么bean提供者必须处理不在序列中的超时回调方法。当调用取消方法时,Bean提供者必须处理计时器到期事件中对超时回调方法的无关调用
一般情况下,超时回调方法能够与组件接口的业务方法或者消息监听器接口的方法一样执行相同的操作。表格2,3,4和10中描述了可以由超时回调方法执行的操作。
由于超时回调方法是bean类的内部方法,因此它没有客户安全上下文。当在超时回调方法内部调用getCallerPrincipal时,它返回未授权标识的容器代表。
如果受时间管理的对象需要使用计时器的标识来识别计时器到期的含义,那么它可以使用equals方法来与其他的到期计时器引用进行比较。
如果计时器是一个单行为的计时器,那么容器在超时回调方法成功调用后删除该计时器(例如,当为超时回调方法启动的事务提交时)。如果在超时回调方法终止后调用计时器上的方法,则抛出NoSuchObjectLocalException。
1.2.3    Timer和TimerHandle接口
Javax.ejb.Timer接口允许bean提供者取消计时器和获取计时器的信息。
Javax.ejb.TimerHandle接口允许bean提供者获取可序列化的计时器句柄。由与计时器是本地对象,因此TimerHandle不可以传入bean的远程业务接口,远程接口或web service接口。
这两个接口的方法如下:
public interface javax.ejb.Timer {
public void cancel();
public long getTimeRemaining();
public java.util.Date getNextTimeout();
public javax.ejb.TimerHandle getHandle();
public java.io.Serializable getInfo();
}
public interface javax.ejb.TimerHandle extends java.io.Serializable {
public javax.ejb.Timer getTimer();
}
1.2.4    Timer标识
Bean提供者不能使用“==”来比较计时器。Bean提供者必须使用Timer.equals(Object obj)方法。
1.2.5    事务
通常,企业bean在事务范围内创建计时器。如果随后事务被回滚,那么创建计时器也回滚。
同样,企业bean通常在事务范围内取消计时器。如果事务被回滚,则取消操作被废止。
通常,超时回调方法的事务属性事REQUIRED或REQUIRES_NEW(如果使用配置描述符就是Required或RequiresNew)。如果事务被回滚,容器会重试超时。
注意:如果使用REQUIRED(Required)事务属性,容器必须启动新事务。允许有事务属性值是为了超时回调方法的事务属性规范和其他的一样。
1.3    Bean提供者的责任
本节描述bean提供者的责任。
1.3.1    企业bean类
注册到Timer服务的企业bean必须有一个超时回调方法。企业bean的class可以有超类和/或超类接口。如果bean的class有超类,则超时回调方法可以定义在这个bean的class上,也可以定义在它的任何超类上。
1.3.2    TimerHandle
由于TimerHandle接口扩展了java.io.Serialiazable,因此客户可以序列化这个句柄。序列化后的句柄可以用于以后获取计时器标识的引用。TimerHandle用于存储计时器。
TimerHandle不可以作为企业bean的远程业务接口、远程接口或web service方法的参数或返回值。
1.4    容器的职责
本节描述支持EJB计时器服务的容器提供者的职责。
1.4.1    TimerService,Timer和TimerHandle接口
容器必须提供TimerService,Timer和TimerHandle接口的实现。
Timer实例不可以是可序列化的。
容器必须实现计时器句柄用于超越计时器的生命期。
容器必须提供相应的Timer.equals(Object obj)和hashCode()的实现。
1.4.2    Timer到期和超时回调方法
在时间到期时或绝对时间点之后容器必须调用超时回调方法。计时器服务必须在计时器创建时开始计时。容器必须调用计时器到期的超时回调方法。
如果使用容器管理的事务划分并且事务属性指定或缺省为REQUIRED或REQUIRED_NEW(如果使用配置描述符则为Required或RequiresNew),容器必须在调用超时回调方法之前启动一个新的事务。如果事务失败或被回滚,那么容器必须至少重试回调方法一次。
如果EJB2.1实体bean的计时器到期并且这个bean已经被钝化,那么容器必须在调用超时回调方法之前调用ejbActivate和ejbLoad方法,参见8.5.3和10.1.4.2章节。
如果计时器是一个单事件计时器,容器必须清除计时器。如果在超时回调方法完成之后调用计时器上的方法,则容器必须抛出javax.ejb.NoSuchObjectLocalException。
如果bean提供者在超时回调方法内调用setRollbackOnly,那么容器必须在超时回调方法内回滚事务。这可以削除计时器到期的影响。在事务回滚后容器必须重试超时回调方法。
计时器是一个持久化对象。在容器崩溃时,所有在容器重启之前的时间内到期的单事件计时器必须在重启时调用超时回调方法。所有在重启之前到期的间隔计时器在重启时至少调用一次。
1.4.3    计时器的取消
当调用计时器的cancel方法时,容器必须清除该计时器。如果随后调用该计时器上的方法,容器必须抛出javax.ejb.NoSuchObjectLocalException。
如果在取消计时器时发生的事务回滚,如果计时器还没有被取消,那么容器必须恢复计时器的持续时间。如果计时器在事务失败的时间点到期,那么在事务回滚后通知到期的计时器。
1.4.4    实体bean的删除
如果实体bean被删除,那么容器必须清除这个bean上的所有计时器。
 
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页