EJB CORE规范(第十四章 异常)

1         异常处理
1.1          概述和概念
1.1.1        应用异常
应用异常是由Bean提供者定义的作为应用业务逻辑的一部分的异常。在这个规范中,应用异常和系统异常是不同的。
企业bean的业务方法使用应用异常来将不正确的应用级条件通知给客户端,例如不能从业务方法的入参中获取值。一般地,客户端可以从应用异常中恢复。应用异常不应当用于报告系统级的问题。
例如,Account企业bean可以抛出应用异常来报告由于余额不足而不能执行借贷操作的异常。但Account不能用应用异常来报告类似数据库连接失败的异常。
应用异常可以定义在企业bean业务接口、home接口、组件接口、消息监听器接口或web service终点的throws子句中。
应用异常可以是java.lang.Exception的直接或间接子类(例如“受检查异常(checked exception)”),或者应用异常可以定义为java.lang.RuntimeException的子类(“未经检查的异常”(unchecked exception))。应用异常不可以是java.rmi.RemoteException的子类。java.rmi.RemoteException和它的子类是保留的系统异常。
Javax.ejb.CreateException,javax.ejb.RemoveException,javax.ejb.FinderException以及它们的子类看作是应用异常。这些异常用作标准应用异常向客户端报告来自2.1中EJBHome和/或EJBLocalHome接口的create、remove和finder方法的错误(参见8.5.10和10.1.11章节)。在本章中定义的应用异常规则涉及了这些异常。
1.1.2        异常处理的目标
EJB规范中设计的异常处理要满足以下高层目标:
由企业bean实例抛出的应用异常应当被准确无误的报告给客户端(也就是,客户端得到同一个异常)(注:使用web service协议时可以不同,参见【25】)。
由企业bean实例抛出的应用异常不应当自动回滚客户端事务,除非应用被异常定义用来引起事务回滚。一般地,客户端应当给一个从应用异常恢复事务的机会。
能够安全地处理未知异常,这些异常可能使得实例的状态变量和/或后台的持久化数据处于不一致的状态。
1.2          Bean提供者的责任
本节描述考虑异常处理的Bean提供者的视图和责任。
1.2.1        应用异常
Bean提供者定义应用异常。被检查的应用异常可以定义在企业bean业务接口、home接口、组件接口、消息监听器接口或web service终点的throws子句中。未经检查的应用异常通过用ApplicationException注释符注入,或在配置文件中用application-exception元素声明。
由于应用异常用于由客户端处理,而不是由系统管理员处理,因此它们应当只报告业务逻辑异常,而不是报告系统级异常。。
某些消息类型可以在消息监听器的接口中定义应用异常。在用于特定消息类型的资源适配器来决定如何处理这些异常。参见【15】。
Bean提供者负责从业务方法中抛出合适的应用异常来向客户端报告业务逻辑异常。
应用异常不字段标记事务回滚,除非ApplicationException注释符应用到异常类并且指定rollback元素为true,或者在配置文件的application-exception中指定rollback元素为true。application-exception元素的子元素rollback可以显式指定来覆盖由ApplicationException注释符缺省或指定的rollback值。
Bean提供者在从企业bean实例抛出应用异常之前,必须做下面两件事的一个来保证数据的完整性:
确保实例处于一种状态,在这种状态下客户端即使继续和/或提交事务也不会引起数据完整性丢失。例如,实例在实例执行数据库更新之前抛出一个应用异常表示入参的值无效。
如果应用异常没有指定为引起事务回滚,在抛出应用异常之前用EJBContext.setRollbackOnly方法来标记事务回滚。标记事务回滚以确保事务不会被提交。
Bean提供者也有责任在写EJB2.1的bean和早期的客户端视图时使用标准的EJB应用异常(javax.ejb.CreateException,javax.ejb.RemoveException,javax.ejb.FinderException,和它们的子类)。EJB2.1的bean和早期的客户端视图在8.5.10和10.1.11章节中描述。
Bean提供者可以定义标准EJB应用异常的子类,并在企业bean方法中抛出这些子类的实例。一般地,子类为捕捉异常的客户端提供了更多的信息。
1.2.2        系统异常
系统异常是一个java.rmi.RemoteException(或它的子类)或者是一个不是应用异常的RuntimeException。
本节描述Bean提供者如何处理在会话或实体bean的业务方法、消息驱动bean的消息监听器方法、拦截器方法或回调方法(例如,ejbLoad)执行期间可能遭遇各种系统级异常和错误。
企业bean的业务方法、消息驱动bean的消息监听器方法、业务方法的拦截器方法或生命周期回调拦截器方法可能遭遇各种阻止方法成功完成的异常或错误。一般地,发生这种情况是因为这些异常和错误是不期望的,或者是期望的但EJB提供者不知道如何从异常中恢复。这种异常和错误可以是:数据库连接失败,JNDI异常,不期望的来自其他企业bean的RemoteException(注:注意企业bean的业务方法可以从RemoteException中恢复。这里是指业务方法不希望从RemoteException中恢复的情况),不期望的RuntimeException,JVM错误,等等。
如果企业bean遭遇不允许方法成功完成的系统级异常或错误,那么业务方法应当抛出与方法的throws子句匹配的非应用异常。但是EJB规范没有规定异常的确切用法,它鼓励Bean提供者遵循下面的指南:
如果bean方法遭遇系统异常或错误,那么它应当简单地将错误从bean方法迁移到容器(也就是,bean方法不必捕捉异常)。
如果bean方法执行一个引起bean方法不能从中恢复的被检查异常(注:被检查异常不是java.lang.RuntimeException的子类)的操作,那么bean方法应当抛出封装了原始异常的javax.ejb.EJBException。
任何其他的未期望错误应当使用javax.ejb.EJBException来报告。
注意:javax.ejb.EJBException是java.lang.RuntimeException子类,因此它不必列在业务方法的throws子句中。
容器捕捉非应用异常;记录它(这些记录用于警告系统管理员);然后除消息驱动bean外其他的都抛出javax.ejb.EJBException(注:如果业务接口是一个继承了java.rmi.Remote的远程业务接口,那么向客户端抛出的是java.rmi.RemoteException)或者如果使用web service客户端视图,那么抛出java.rmi.RemoteException。如果使用EJB2.1客户端视图,如果客户端是远程客户端则容器抛出java.rmi.RemoteException(或者它的子类),如果是本地客户端,则抛出javax.ejb.EJBException(或它的子类)。对于消息驱动bean,容器记录异常然后抛出封装了原始异常的javax.ejb.EJBException到资源适配器。(参见【15】)
客户端可见的异常在14.3章节描述。异常由通过容器或/和bean抛出的异常和客户端视图共同决定。
当捕捉到一个非应用异常时,Bean提供者可以依赖容器来执行下述的任务:
Bean方法参与的事务将被回滚。
抛出非应用异常的实例的方法将不再被调用。
这意味着:bean提供者不必在抛出非应用异常之前执行任何清理动作。由容器负责清理。
1.2.2.1         Javax.ejb.NoSuchEntityException
.NoSuchEntityException是EJBException的子类。它应当由EJB2.1的实体bean的方法抛出,以表示后台实体已经被从数据库中移除了。
Bean管理的持久化实体bean一般从ejbLoad和ejbStore方法、以及实现了业务接口中定义的业务方法中抛出异常。
1.3          容器提供者的责任
本节描述容器提供者的对于异常处理的责任。EJB架构指定了下列异常的容器行为:
从会话和实体bean的业务方法,包括会话bean的业务方法的拦截器方法中抛出的异常。
从消息驱动bean监听器方法和业务方法的拦截器方法中抛出的异常。
从超时回调方法中抛出的异常。
来自容器对企业bean的其他回调方法中的异常。
来自容器管理事务分割管理的异常
1.3.1        来自会话bean业务接口方法的异常
表14指定了容器如何处理由使用容器管理事务分割的bean的业务接口方法抛出的异常,包括由业务方法拦截器方法抛出的异常。这个表指定了容器的行为是作为一个条件函数,在这个条件下业务接口方法执行和抛出异常。这个表也解释了客户端将要收到的异常以及客户端如何从异常中恢复。(14.4章节详细的描述了异常的客户端视图)。符号“AppException”指应用异常。
表14 由使用容器管理事务分割的bean的业务接口方法抛出的异常的处理
方法条件
方法异常
容器行为
客户端视图
Bean方法运行在调用者的事务上下文中【注意A】。
这种情况可以发生在事务属性是Required、Mandatory和Supports。
AppException
直接抛出AppException。如果应用异常指定为产生回滚事务,则标记事务回滚。
接收AppException。除非应用异常指定为引起事务回滚,否则可以继续在事务中计算并最终提交事务。
所有其他的异常和错误
记录异常和错误【注意 B】。
标记事务回滚。
丢弃实例【注意C】
抛出javax.ejb.EJBTransactionRolledbackException到客户端【注意 D】
接收javax.ejb. EJBTransactionRolledbackException
继续事务是无效的。
Bean方法运行在容器在分发业务方法之前即时启动的事务上下文中。
这种情况可以发生在事务属性是Required和RequiresNew。
AppException
如果实例调用setRollbackOnly(),那么回滚事务,并再次抛出AppException。
如果应用指定为引起事务回滚,那么标记事务回滚,然后再次抛出AppException
接收AppException。
如果客户端在一个事务中执行,则客户端的事务不标记回滚,客户端可以继续工作。
所有其他异常
记录异常或错误。
回滚容器启动的事务。
丢弃实例。
抛出EJBException到客户端。【注意E】
接收EJBException。
如果客户端在一个事务中执行,那么客户端的事务可以标记为回滚,也可以不标记。
Bean方法运行在未指定的事务上下文中。
这种情况发生在事务属性是NotSupported、Never和Supports。
AppException
再次抛出AppExcepton
接收AppException。
如果客户端在一个事务中执行,则客户端的事务不标记回滚,客户端可以继续工作。
所有其他异常
记录异常或错误。
丢弃实例。
抛出EJBException到客户端。【注意F】
接收EJBException。
如果客户端在一个事务中执行,那么客户端的事务可以标记为回滚,也可以不标记。
注意:
【A】:调用者可以是另外一个企业bean或一个任意的客户端程序。
【B】:“记录异常或错误”意思是容器记录异常或错误以便系统管理员发现问题。
【C】:“丢弃实例”意思是容器不必调用任何业务方法或实例上的容器回调方法。
【D】:如果业务接口是继承了java.rmi.Remote的远程业务接口,那么avax.ejb.EJBTransactionRolledbackException被抛到接收异常的客户端。
【E】:如果业务接口是继承了java.rmi.Remote的远程业务接口,那么avax.ejb.RemoteException被抛到接收异常的客户端。
【F】:如果业务接口是继承了java.rmi.Remote的远程业务接口,那么avax.ejb.RemoteException被抛到接收异常的客户端。
表15指定了容器必须如何处理由使用bean管理事务分割的bean的业务方法抛出的异常,包括由业务方法的拦截器方法抛出的异常。这个表指定了容器的行为是作为一个条件函数,在这个条件下业务接口方法执行和抛出异常。这个表也解释了客户端将要收到的异常以及客户端如何从异常中恢复。(14.4章节详细的描述了异常的客户端视图)。
表15 对由使用bean管理事务分割的会话bean业务接口抛出的异常的处理
Bean方法条件
Bean方法异常
容器行为
客户端接收
Bean是有状态或无状态的会话bean
AppException
再次抛出AppException
接收AppException
所有其他异常
记录异常或错误。
标记由实例已经启动的事务回滚,但还没有结束。
抛出EJBException到客户端。【注意 A】
接收EJBException
注意:
【A】:如果业务接口是继承了java.rmi.Remote的远程业务接口,那么avax.ejb.RemoteException被抛到接收异常的客户端。
1.3.2        来自通过会话或实体bean的2.1客户端视图或通过Web服务客户端视图调用的方法的异常
在这里的业务方法认为是定义在企业bean业务接口、home接口、组件接口或web服务终端(包括它们的父类)内的方法;以及下列会话bean或实体bean方法:ejbCreate<METHOD>,ejbPostCreate<METHOD>,ejbRemove,ejbHome<METHOD>和ejbFind<METHOD>。
表16指定了容器如何处理由使用容器管理事务分割的bean的业务接口方法抛出的异常,包括由业务方法拦截器方法抛出的异常。这个表指定了容器的行为是作为一个条件函数,在这个条件下业务接口方法执行和抛出异常。这个表也解释了客户端将要收到的异常以及客户端如何从异常中恢复。(14.4章节详细的描述了异常的客户端视图)。符号“AppException”指应用异常。
表16 处理由使用容器管理事务分割的web服务客户端视图或EJB2.1客户端视图的方法抛出的异常
方法条件
方法异常
容器行为
客户端视图
Bean方法运行在调用者的事务上下文中【注意A】。
这种情况可以发生在事务属性是Required、Mandatory和Supports。
AppException
再次抛出AppException。如果应用异常指定为产生回滚事务,则标记事务回滚。
接收AppException。除非应用异常指定为引起事务回滚,否则可以继续在事务中计算并最终提交事务(如果实例调用setRollbackOnly则提交将会失败)。
所有其他的异常和错误
记录异常和错误【注意 B】。
标记事务回滚。
丢弃实例【注意C】
抛出javax.transaction.TransactionRolledbackException到远程客户端;抛出javax.ejb.EJBTransactionRolledbackException到本地客户端。
接收javax.transaction.TransactionRolledbackException或javax.ejb. EJBTransactionRolledbackException
继续事务是无效的。
Bean方法运行在容器在分发业务方法之前即时启动的事务上下文中。
这种情况可以发生在事务属性是Required和RequiresNew。
AppException
如果实例调用setRollbackOnly(),那么回滚事务,并再次抛出AppException。
如果应用指定为引起事务回滚,那么标记事务回滚,然后再次抛出AppException。
否则,尽量提交事务然后再次抛出AppException。
接收AppException。
如果客户端在一个事务中执行,则客户端的事务不标记回滚,客户端可以继续工作。
所有其他异常
记录异常或错误。
回滚容器启动的事务。
丢弃实例。
抛出RemoteException到远程或web服务客户端。【注意D】;抛出EJBException到本地客户端。
接收RemoteException或EJBException。
如果客户端在一个事务中执行,那么客户端的事务可以标记为回滚,也可以不标记。
Bean方法运行在未指定的事务上下文中。
这种情况发生在事务属性是NotSupported、Never和Supports。
AppException
再次抛出AppExcepton
接收AppException。
如果客户端在一个事务中执行,则客户端的事务不标记回滚,客户端可以继续工作。
所有其他异常
记录异常或错误。
丢弃实例。
抛出RemoteException到远程或web服务客户端。抛出EJBException到本地客户端。
接收RemoteException或EJBException。
如果客户端在一个事务中执行,那么客户端的事务可以标记为回滚,也可以不标记。
注意:
【A】:调用者可以是另外一个企业bean或一个任意的客户端程序。这种情况不适用于web服务终端的方法。
【B】:“记录异常或错误”意思是容器记录异常或错误以便系统管理员发现问题。
【C】:“丢弃实例”意思是容器不必调用任何业务方法或实例上的容器回调方法。
【D】:抛出RemoteException到web服务客户端意思是容器映射RemoteException到对应的SOAP错误。参见【25】
表17指定了容器必须如何处理由使用bean管理事务分割的bean的业务方法抛出的异常,包括由业务方法的拦截器方法抛出的异常。这个表指定了容器的行为是作为一个条件函数,在这个条件下业务接口方法执行和抛出异常。这个表也解释了客户端将要收到的异常以及客户端如何从异常中恢复。(14.4章节详细的描述了异常的客户端视图)。
表17 对由使用bean管理事务分割的会话bean业务接口抛出的异常的处理
Bean方法条件
Bean方法异常
容器行为
客户端接收
Bean是有状态或无状态的会话bean
AppException
再次抛出AppException
接收AppException
所有其他异常
记录异常或错误。
标记回滚由实例已经启动的但还没有完成的事务。
丢弃实例。
抛出RemoteException到远程客户端或web服务客户端【注意 A】;抛出EJBException到本地客户端。
接收RemoteException或EJBException
注意:
【A】:抛出RemoteException到web服务客户端意思是容器映射RemoteException到对应的SOAP错误。参见【25】
1.3.3        来自带Web服务客户端视图的无状态会话bean的PostConstruct和PreDestroy方法的异常
表18指定容器如何处理由带Web服务客户端视图的无状态会话bean的PostConstruct和PreDestroy方法抛出的异常。
表18 由带Web服务客户端视图的无状态会话bean的PostConstruct和PreDestroy方法抛出的异常的处理
Bean方法条件
Bean方法异常
容器动作
Bean是带web服务客户端视图的无状态会话bean
系统异常
记录异常或错误。
丢弃实例。
1.3.4        来自消息驱动bean消息监听器方法的异常
本节指定容器如何处理来自消息驱动bean消息监听器方法的异常。
表19指定了容器如何处理由使用容器管理事务分割的消息驱动bean的消息监听器方法抛出的异常,包括由业务方法拦截器方法抛出的异常。这个表指定了容器的行为是作为一个条件函数,在这个条件下业务接口方法执行和抛出异常。
表19 对由使用容器管理事务分割的消息驱动bean的消息监听器方法抛出的异常的处理
方法条件
方法异常
容器动作
Bean方法运行在调用者的事务上下文中【注意A】。
这种情况可以发生在事务属性是Required。
AppException
如果应用异常指定为产生回滚事务,则标记事务回滚。
如果实例调用setRollbackOnly,则回滚事务然后再次抛出AppException到资源适配器。
否则,若应用异常没有指定为产生事务回滚则尽力提交事务并再次抛出AppException。
系统异常
记录异常或错误【注意A】。
回滚容器启动的事务。
丢弃实例【注意B】。
抛出封装了原始异常的EJBException到资源适配器。
Bean方法运行在未指定的事务上下文中。
这种情况发生在事务属性是NotSupported。
AppException
再次抛出AppException到资源适配器。
系统异常
记录异常或错误。
回滚容器启动的事务。
丢弃实例。
抛出封装了原始异常的EJBException到资源适配器。
注意:
【A】:“记录异常或错误”意思是容器记录异常或错误以便系统管理员发现问题。
【B】:“丢弃实例”意思是容器不必调用该实例上的任何方法。
表20指定了容器如何处理由使用bean管理事务分割的消息驱动bean的消息监听器方法抛出的异常,包括由业务方法拦截器方法抛出的异常。这个表指定了容器的行为是作为一个条件函数,在这个条件下业务接口方法执行和抛出异常。
表20 对由使用bean管理事务分割的消息驱动bean的消息监听器方法抛出的异常的处理
Bean方法条件
Bean方法异常
容器动作
Bean是消息驱动bean
AppException
再次抛出AppException到资源适配器。
系统异常
记录异常或错误。
标记回滚由实例启动的但还没有完成的事务。
丢弃实例。
抛出封装了原始异常的EJBException到资源适配器。
1.3.5        来自消息驱动bean的PostConstruct和PreDestroy方法的异常
表21指定了容器必须如何处理由消息驱动bean的PostConstruct和PreDestroy方法抛出的异常。
表21对由消息驱动bean的PostConstruct和PreDestroy方法抛出的异常的处理
Bean方法条件
Bean方法异常
容器动作
Bean是消息驱动bean
系统异常
记录异常或错误。
丢弃实例。
1.3.6        来自企业bean的超时回调方法的异常
本节指定容器如何处理由企业bean的超时回调方法抛出的异常。
表22和表23指定容器必须如何处理由企业bean的超时回调方法抛出的异常。超时回调方法不抛出应用异常也不能将异常抛到客户端。
表22 对由使用容器管理事务分割的企业bean的超时回调方法抛出的异常的处理
方法条件
方法异常
容器动作
Bean超时回调方法运行在在分派方法之前由容器启动的事务上下文中
系统异常
记录异常或错误【注意A】。
回滚容器启动的事务。
丢弃实例【注意B】。
 
注意:
【A】:“记录异常或错误”意思是容器记录异常或错误以便系统管理员发现问题。
【B】:“丢弃实例”意思是容器不必调用该实例上的任何方法。
表23 对由使用bean管理事务分割的企业bean的超时回调方法抛出的异常的处理
方法条件
方法异常
容器动作
Bean超时回调方法可以使用UserTransaction。
系统异常
记录异常或错误【注意A】。
标记回滚实例启动的但还没有完成的事务。
丢弃实例【注意B】。
 
注意:
【A】:“记录异常或错误”意思是容器记录异常或错误以便系统管理员发现问题。
【B】:“丢弃实例”意思是容器不必调用该实例上的任何方法。
1.3.7        来自容器调用的其他回调方法的异常
本节指定容器如何处理由容器调用的其他回调方法的抛出异常。这节适用于以下回调方法:
依赖注入方法。
EntityBean接口的ejbActivate、ejbLoad、ejbPassivate、ejbStore、setEntityContext和unsetEntityContext方法。
SessionBean接口的PostActivate和PrePassivate回调方法,以及/或ejbActivate、ejbPassivate和setSessionContext方法。
MessageDrivenBean接口的setMessageDrivenContext方法。
SessionSynchronization接口的afterBegin、beforeCompletion和afterCompetion方法。
容器必须按照下列方式处理来自这些方法的异常:
记录异常或错误以引起系统管理员的注意。
如果实例在事务中,则标记事务回滚。
丢弃实例(也就是容器不可以调用实例上的任何业务方法或容器回调方法)。
如果异常或错误发生在客户端调用方法的处理过程中,那么抛出javax.ejb.EJBException(注:如果业务接口是继承了java.rmi.Remote的远程业务接口,则抛出java.rmi.RemoteException)。如果使用EJB2.1客户端视图或web服务客户端实体,那么如果客户端是远程客户端则抛出java.rmi.RemoteException,如果客户端是本地客户端则抛出javax.ejb.EJBException。如果实例在客户端事务中执行,那么容器应当抛出javax.ejb.EJBTransactionRolledbackException(注:如果业务接口是继承了java.rmi.Remote的远程业务接口,则抛出javax.transaction.TransactionRolledbackException)。使用EJB2.1客户端视图或web服务客户端视图,则容器应当向远程客户端抛出javax.transaction. TransactionRolledbackException或向本地客户端抛出javax.ejb. TransactionRolledbackException,因为它为客户端提供了更多的信息。(客户端知道事务不能继续了)
1.3.8        javax.ejb.NoSuchEntityException
NoSuchEntityException是EJBException的子类。如果它被一个实体bean抛出,那么容器必须使用在章节14.3.2,14.3.4和14.3.7中描述的处理EJBException的规则来处理它。
为了告诉客户端错误的原因,容器应当抛出java.rmi.NoSuchObjectException(它是java.rmi.RemoteException的子类)到远程客户端或抛出javax.ejb.NoSuchObjectLocalException到本地客户端。
1.3.9        不存在的无状态会话或实体对象
如果客户端调用已经移除的无状态会话或实体对象,则容器应当抛出javax.ejb.NoSuchEJBException(注:如果业务接口继承了java.rmi.Remote,则抛出java.rmi.NoSuchObjectException)。如果使用EJB2.1客户端视图,容器应当向远程客户端抛出java.rmi.NoSuchObjectException(它是java.rmi.RemoteException的子类),向本地客户端抛出javax.ejb.NoSuchObjectException。
1.3.10   来自对容器管理的事务进行管理的异常
容器有责任启动和提交容器管理的事务,正如在13.6.2章节中所述。本节指定了容器必须如何处理由启动和提交事务操作抛出的异常。
如果容器不能启动或提交容器管理的事务,容器必须抛出javax.ejb.EJBException(如果业务接口继承了java.rmi.Remote,则抛出java.rmi.RemoteException)。如果使用EJB2.1客户端视图或web服务客户端,那么容器必须抛出java.rmi.RemoteException到远程或web服务客户端,抛出javax.ejb.EJBException到本地客户端。在容器不能为消息驱动bean或超时回调方法启动或提交容器管理的事务的情况下,容器必须抛出并记录javax.ejb.EJBException.
但是,容器不应当抛出javax.ejb.EJBException或java.rmit.RemoteException或由于实例在EJBContext对象上调用了setRollbackOnly方法而回滚事务。在这种情况下,容器必须回滚事务,并且将业务方法的结果或业务方法抛出的应用异常传给客户端。
注意:某些容器实现可以透明地重试失败的事务,客户端和企业bean的代码都不知道。这种容器将在重试一定次数后抛出javax.ejb.EJBExceptoin或java.rmi.RemoteException
1.3.11   资源释放
当容器由于系统异常丢弃实例时,容器应当释放由该实例获得的所有资源,这些所需的资源通过声明在bean环境的资源工厂获得(参见16.7)。
注意:当容器应当释放通过声明在bean环境的资源工厂获得的对资源管理器的连接时,通常情况下,容器不能释放“不受管理的”资源,这些资源由实例通过JDK API获得。例如,如果实例已经打开了一个TCP/IP连接,许多容器实现将不能够释放连接。连接最终由JVM的垃圾回收机制释放。
1.3.12   支持废弃的java.rmi.RemoteException用法
EJB1.0规范允许业务方法、ejbCreate、ejbPostCreate、ejbFind<METHOD>、ejbRemove和容器调用的回调方法(也就是定义在EntityBean、SessionBean和SessionSynchronization接口内的方法)在企业bean类中实现,这些实现用java.rmi.RemoteException来向容器报告非应用异常。
java.rmi.RemoteException的这种用法在EJB1.1中被废弃——按照EJB1.1规范写的企业bean应当用javax.ejb.EJBException,用EJB2.0或以后版本写的必须用javax.ejb.EJBException。
EJB1.1和EJB2.0或以后规范要求容器支持java.rmi.RemoteException废弃的这种用法。容器应当将由企业bean方法抛出的java.rmi.RemoteException和javax.ejb.EJBException同等对待。
1.4          异常的客户端视图
本节描述接收来自企业bean调用的异常的客户端视图。
客户端可以通过以下方式获取企业bean:通过企业bean的业务接口(无论是local还是remote)、通过企业bean的远程home和远程接口、通过企业bean的本地home和本地接口,或通过企业bean的web服务客户端视图(这要依赖于客户端是用EJB3.0 API还是用早期的API,以及客户端是否是远程客户端、本地客户端还是web服务客户端)。
一般地,业务接口的方法不管接口是远程还是本地接口都不会抛出java.rmi.RemoteException。
远程home接口,远程接口和web服务终端接口都是Java RMI接口,因此它们的方法(包括从父类继承来的方法)的throws子句包括必须的java.rmi.RemoteException。它们的throws子句可以包括任意数量的应用异常。
本地home和本地接口都是Java本地接口,因此它们的方法(包括从父类继承来的方法)的throws子句不包括java.rmi.RemoteException。它们的throws子句可以包括任意数量的应用异常。
1.4.1        应用异常
1.4.1.1         本地和8 远程客户端
如果客户端程序收到来自企业bean调用的应用异常,那么客户端可以继续调用企业bean。应用异常不会引起EJB对象的移除。
尽管容器不会因为应用异常自动标记事务回滚,但是事务可以由企业bean实例抛出应用异常之前标记为回滚,或应用异常已经被指定为要求容器回滚事务。由两种方式来知道某个异常是否引起事务回滚:
静态绑定:程序员可以检查企业bean的客户端视图接口的文档。Bean提供者可能已经指定(尽管不要求这么做)应用异常在抛出异常之前企业bean标记事务回滚。
动态绑定:使用容器管理事务的企业bean的客户端可能使用javax.ejb.EJBContext对象的getRollbackOnly方法来明白目前的事务是否已经被标记回滚;其他的客户端可以使用javax.transaction.UserTransaction接口的getStatus来获取事务的状态。
1.4.1.2         Web服务客户端
如果无状态会话bean从它的web服务方法中抛出应用异常,那么它容器负责将异常映射到在WSDL中指定的SOAP错误,这个WSDL是描述了无状态会话bean实现的端口类型。对于java客户端,客户端接收的异常由在【25】中映射规则来描述。
1.4.2        Java.rmi.RemoteException和javax.ejb.EJBException
如上所述,客户端以收到javax.ejb.EJBException或java.rmi.RemoteException来表明它调用企业bean方法或正确完成调用失败。异常可以由容器或客户端与容器之间的通信子系统抛出。
一般情况下,如果客户端从方法调用收到javax.ejb.EJBException或java.rmi.RemoteException,那么它不知道企业bean的方法是否完成。
如果客户端在事务上下文中执行,则客户端事务可以或不必由通信子系统或目标bean的容器标记为回滚。
例如,如果后台事务服务器或目标bean的容器由于业务方法部分完成而担心数据的完整性,那么事务将被标记为回滚。例如当目标bean的方法由于RuntimeException而返回,或如果远程服务器在业务方法执行期间宕机,那么就会发生业务方法的部分完成。
标记事务回滚不是必需的。例如当在客户端的通信子系统不能将请求发送到服务器时,就可以不标记事务回滚。
当在事务上下文中执行的客户端从企业bean调用中收到EJBException或RemoteException,那么客户端可以使用下列的策略来处理异常:
停止事务。如果客户都是事务的发起者,那么它可以简单的回滚它的事务。如果客户端不是事务的发起者,那么它可以标记事务回滚或执行引起事务回滚的操作。例如,如果客户端是一个企业bean,那么企业bean可以抛出一个RuntimeException来让容器回滚事务。
继续事务。客户端可以在同一个或其他的企业bean上执行附加的操作,并最后试着提交事务。如果事务在EJBException或RemoteException被抛到客户端时被标记为回滚,那么提交会失败。
如果客户端选择继续事务,那么客户端可以首先查询事务的状态以避免在以标记为回滚的事务上进行无用的计算。如果客户端是使用容器管理事务分割的企业bean ,那么它可以使用EJBContext.getRollbackOnly方法来测试事务是否已经被标记为回滚;如果客户端是使用bean管理事务分割的企业bean或其他客户端类型,则它可以使用UserTransaction.getStatus方法来得到事务的状态。
1.4.2.1         Javax.ejb.EJBTransactionRolledbackException,javax.ejb.TransactionRolledbackLocalException和javax.transaction.TransactionRolledbackException
Javax.ejb.EJBTransactionRolledbackException,javax.ejb.TransactionRolledbackLocalException和都是Javax.ejb.EJBException的子类。javax.transaction.TransactionRolledbackException是java.rmi.RemoteException的子类。它在JTA标准扩展中定义。
如果客户端接收到这些异常,那么客户端一定知道事务已经被回滚。它继续这个事务也是无用的,因为事务不再会被提交。
1.4.2.2         Java.ejb.EJBTransactionRequiredException,javax.ejb.TransactionRequiredLocalException和javax.transaction.TransactionRequiredException
Java.ejb.EJBTransactionRequiredException和javax.ejb.TransactionRequiredLocalException是javax.ejb.EJBException的子类。javax.transaction.TransactionRequiredException是java.rmi.RemoteException的子类。它被定义在JTA标准的扩展中。
Java.ejb.EJBTransactionRequiredException,javax.ejb.TransactionRequiredLocalException和javax.transaction.TransactionRequiredException通知客户端目标企业bean必须在客户端的事务中被调用,但调用企业bean的客户端没有事务上下文。
这个错误通常表示应用没有被正确地建立。
1.4.2.3         Javax.ejb.NoSuchEJBException,javax.ejb.NoSuchObjectLocalException和java.rmi.NoSuchObjectException
Javax.ejb.NoSuchEJBException是javax.ejb.EJBException的子类。如果本地业务方法由于EJB对象不存在而不能完成,则会话bean的业务接口向客户端抛出这个异常。
javax.ejb.NoSuchObjectLocalException是javax.ejb.EJBException的子类。如果本地业务方法由于EJB对象不再存在而不能完成,则抛出这个异常。
java.rmi.NoSuchObjectException是java.rmi.RemoteException的子类。如果远程业务方法由于EJB对象不再存在而不能完成,则抛出这个异常。
1.5          系统管理员的职责
系统管理员负责监控由容器记录的非应用异常的日志和错误,并采取行动去纠正引起这些异常和错误的问题。
 
阅读更多
想对作者说点什么?

博主推荐

换一批

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