对容器管理事务的Session Bean和Entity Bean的Home接口和组件接口中定义的方法,以及Message-driven Bean中的onMessage方法,开发者可以设置其事务属性。当客户端通过Home接口或组件接口调用这些方法时,或者当消息到达时onMessage方法被调用时,容器将按照开发者指定的事务属性对以上方法的事务进行管理。
当使用容器管理事务的EJB时,开发者必须指定以下方法的事务属性:
- Session Bean中,除了在javax.ejb.EJBObject接口和javax.ejb.EJBLocalObject接口中定义的方法,其他定义在组件接口中的方法,以及定义在组件接口直接或非直接地继承的接口中的方法,开发者必须指定方法的事务属性。Session Bean的Home接口中的方法不可指定其事务属性;
- Entity Bean中,除了getEJBHome、getEJBLocalHome、getHandler、getPrimaryKey和isIdentical方法之外,其他定义在组件接口中的方法,以及定义在组件接口直接或非直接地继承的接口中的方法,开发者必须指定方法的事务属性。除了远程Home接口中的getEJBMetaData和getHomeHandler方法,其他定义在Home接口中的方法,以及定义在Home接口直接或非直接地继承的接口中的方法,开发者必须指定方法的事务属性;
- Message-driven Bean中,开发者必须指定onMessage方法的事务属性。
开发者可指定的事务属性包括以下几种:NotSupported、Required、Supports、RequiresNew、Mandatory和Never。
下面对这六种事务属性具有的事务语义分别进行描述。
19.3.2.3.1. NotSupported
当某方法的事务属性被指定为NotSupported时,容器将在未指明的事务上下文中调用此方法。具体情形如下:
当客户端请求伴随事务上下文,容器将在调用EJB的业务方法之间,暂停当前线程伴随的事务上下文。当方法调用完成之后,容器恢复前面暂停的事务上下文。伴随客户端调用事务上下文不会传递到资源管理器或业务方法中调用的其他组件。 如此业务方法调用了其他组件,则此调用不伴随任何事务。
当客户端请求不伴随事务上下文,容器也将不在事务上下文中进行此方法调用。
另外,如果方法中调用了其他的组件,则调用将不会伴随事务上下文。
19.3.2.3.2. Required
当某方法的事务属性被指定为Required时,容器将在有效的事务上下文中调用此方法。具体情形如下:
当客户端请求伴随事务上下文,则容器在此事务上下文中调用此业务方法。
如客户端请求不伴随事务上下文,容器在调用此业务方法之前,将自动开始一个新的事务,并在此事务中自动征用(enlist)此业务方法访问的所有事务性资源,如方法中调用了其他的EJB组件,则调用将伴随此容器开始的事务。当容器对业务方法的调用完成,容器将试图提交事务。在方法调用结果返回客户端之前,容器将执行事务的提交协议(如两阶段提交协议)。
19.3.2.3.3. Supports
当某方法的事务属性被指定为Supports时,容器将按如下规则调用此方法:
- 如客户端请求伴随事务上下文,容器按照事务属性为Required的情况,使用相同步骤进行处理;
- 如客户端请求不伴随事务上下文,容器按照事务属性为NotSupported的情况,使用相同步骤进行处理。
 | 注意 |
使用Supports事务属性时必须注意,因为根据客户端请求是否伴随事务上下文,决定了不同的执行模式,进而决定了不同的方法事务语义,只有在这两种不同的执行模式中都能正确运行的方法,才能考虑使用Supports事务属性。
|
19.3.2.3.4. RequiresNew
当某方法的事务属性被指定为RequiresNew时,容器将在一个新的事务上下文中调用此方法。具体情形如下:
当客户端请求不伴随事务上下文,容器在调用此业务方法之前,将自动开始一个新的事务,并在此事务中自动征用(enlist)此业务方法访问的所有事务性资源,如方法中调用了其他的EJB组件,则调用将伴随此容器开始的事务。当容器对业务方法的调用完成,容器将试图提交事务。在方法调用结果返回客户端之前,容器将执行事务的提交协议(如两阶段提交协议)。
当客户端请求伴随事务上下文,容器在开始一个新的事务和调用业务方法之前,将自动暂停当前客户端线程伴随的事务上下文。在方法调用和容器开始的事务完成之后,容器将恢复前面暂停的客户端事务。
19.3.2.3.5. Mandatory
当某方法的事务属性被指定为Mandatory时,容器将在客户端的事务上下文中调用此方法。客户端调用此方法时,必须伴随事务:
- 如客户端请求伴随事务上下文,容器按照事务属性为Required的情况,使用相同步骤进行处理;
- 如客户端请求不伴随事务上下文,如果客户端为远程客户端,则容器将抛出javax.transaction.TransactionRequiredException异常;如果客户端为本地客户端,则容器将抛出javax.transaction.TransactionRequiredLocalException异常;
19.3.2.3.6. Never
当某方法的事务属性被指定为Never时,容器将不会在任何EJB规范中规定的事务上下文中调用此方法。客户端调用此方法时,不能伴随事务:
- 如客户端请求伴随事务上下文,如果客户端为远程客户端,则容器将抛出java.rmi.RemoteException异常;如果客户端为本地客户端,则容器将抛出javax.ejb.EJBException异常;
- 如客户端请求不伴随事务上下文,容器按照事务属性为NotSupported的情况,使用相同步骤进行处理;