会话 bean 和实体 bean 的事务属性

会话 bean 和实体 bean 可能的属性值包括:

  • Required —— bean 必须始终运行在事务中。如果客户端已经启动一个事务,则 bean 将加入到事务中。如果客户端还没有启动事务,那么 EJB 容器将启动一个新事务。当需要 bean 始终运行在事务中时,请使用该属性。
  • RequiresNew —— bean 始终启动一个新的事务。如果客户端已经启动一个事务,则挂起现有事务,直到新事务已提交或中止。在新事务完成之后,现有事务将继续。当需要 bean 作为一个单独的工作单元运行并展示所有的 ACID 属性时,请使用该属性。
  • Supports —— 如果客户端启动一个事务,则 bean 将加入到事务中。但是,如果事务不存在,EJB 容器不会启动一个新事务。要在企业 bean 上执行非任务关键型操作时,请使用该属性。
  • Mandatory —— 在调用 bean 时客户端必须启动一个事务。这不会创建一个新的事务。在调用 bean 时,如果没有事务已经启动,则将抛出一个异常。当 bean 是某一较大系统的一部分时,请使用该属性。通常可能由第三方负责启动事务。对用户而言,这是一个安全选项,因为它可以确保 bean 将成为事务的一部分。
  • NotSupported —— 在事务中不能调用 bean。如果客户端已经启动一个事务,则挂起现有事务,直到 bean 的方法完成。在完成上述方法之后,现有事务将继续。如果客户端没有启动事务,则不会创建一个新事务。在不需要 bean 展示任何 ACID 属性(比如类似报表的非系统关键型操作)时,请使用该属性。
  • Never —— 如果客户端启动一个事务,则 bean 将抛出一个异常。在您可能永远都不想让您的 bean 参与到事务中的情况下,请使用该属性。




回页首


消息驱动 bean 的事务属性

只有两种消息驱动 bean 消息监听器方法使用的事务属性:

  • NotSupported —— bean 不能参与到事务中。如果客户端启动一个事务,那么现有事务将挂起,直到 bean 的方法完成为止。在完成上述方法之后,现有事务将继续。如果客户端没有启动事务,则不会创建一个新的事务。
  • Required —— bean 必须始终运行在事务中。如果客户端已经启动事务,则 bean 将加入到事务中。如果客户端没有启动事务,则 EJB 容器将启动一个新事务。

在为企业 bean 方法确定正确事务属性之后,就可以配置 EJB 部署描述符了。





回页首


配置 EJB 部署描述符

对于每个企业 bean,都要在部署描述符中配置事务的下列两个部分:

  • 在 EJB 部署描述符中使用 <transaction-type> 元素指定 bean 使用的是容器管理的事务还是 bean 管理的事务。可能的值是 containerbean。由于实体 bean 必须使用容器管理的事务,这只对会话 bean 和消息驱动 bean 是必需的。
  • 对于容器管理的事务,您可以为企业 bean 的方法随意指定事务属性。在 EJB 部署描述符中的 <container-transaction> 部分指定它。清单 1 中显示了每种方法的通用格式。

清单 1. 每种方法的通用格式
<method>
            <ejb-name>EJBNAME</ejb-name>
            <method-name>METHODNAME</method-name>
            <trans-attribute>TRANSATTRIBUTE</trans-attribute>
            </method>
            

TRANSATTRIBUTE 可能的值有:

  • NotSupported
  • Required
  • Supports
  • RequiresNew
  • Mandatory
  • Never

也可以对企业 bean 的所有方法指定事务属性。对 <method-name> 属性使用 *

清单 2 显示了为容器管理的企业 bean 指定事务属性的示例。除了为 updateClaimNumber 方法分配 Mandatory 属性以外,ClaimRecord企业 bean 为所有方法都分配了 Required 属性。Coverage bean 对所有方法指派 RequiresNew 属性。


清单 2. ejb 部署描述符文件中的事务属性
<ejb-jar>
            ...
            <assembly-descriptor>
            ...
            <container-transaction>
            <method>
            <ejb-name>ClaimRecord</ejb-name>
            <method-name>*</method-name>
            </method>
            <trans-attribute>Required</trans-attribute>
            </container-transaction>
            <container-transaction>
            <method>
            <ejb-name>ClaimRecord</ejb-name>
            <method-name>updateClaimNumber</methodname>
            </method>
            <trans-attribute>Mandatory</trans-attribute>
            </container-transaction>
            <container-transaction>
            <method>
            <ejb-name>Coverage</ejb-name>
            <method-name>*</method-name>
            </method>
            <trans-attribute>RequiresNew</trans-attribute>
            </container-transaction>
            ...
            </assembly-descriptor>
            ...
            </ejb-jar>