會話 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>