通過使用@TransactionAttribute 注釋或部署描述符,開發(fā)者能夠指定事務屬性。EJB 容器通過分析事務屬性便能夠知道如何處理EJB 組件的事務需求。EJB 事務屬性的取值有:
(1 )Required ,如果EJB 組件必須總是運行在事務中,則應該使用Required 模式。如果已經(jīng)有事務在運行,則EJB 組件參與其中;如果沒有事務運行,則EJB 容器會為EJB 組件啟動新的事務。
Required 是默認和最常使用的事務屬性值。這個值指定必須在事務之內(nèi)調(diào)用EJB 方法。如果從非事務性客戶端調(diào)用方法,那么容器會在調(diào)用方法之前開始事務,并且在方法返回時結束事務。另一方面,如果調(diào)用者從事務性上下文調(diào)用方法,那么 方法會聯(lián)結已有事務。在從客戶段傳播事務的情況下,如果我們的方法表示應該回滾事務,那么容器不僅回回滾整個事務,而且會向客戶端拋出異常,從而讓客戶端 知道它開始的事務已經(jīng)被另一個方法回滾了。
(2 )Requires_New ,當客戶調(diào)用EJB 時,如果總是希望啟動新的事務,則應該使用RequiresNew 事務屬性,如果客戶在調(diào)用EJB 組件時已經(jīng)存在事務,則當前事務會被掛起,進而容器啟動新的事務,并將調(diào)用請求委派給EJB 組件。也就是說,如果客戶端已經(jīng)有了事務,那么它暫停該事務,知道方法返回位置,新事務是成功還是失敗都不會影響客戶端已有的事務。EJB 組件執(zhí)行相應的業(yè)務操作,容器會提交或回滾事務,最終容器將恢復原有的事務,當然,如果客戶在調(diào)用EJB 組件時不存在事務,則不需要執(zhí)行事務的掛起或恢復操作。
RequiresNew 事務屬性非常有用。如果EJB 組件需要事務的ACID 屬性,并且將EJB 組件運行在單個獨立的工作單元中,從而不會將其他外部邏輯也包括在當前的事務中,則必須使用RequiredNew事 務屬性。如果需要事務,但是不希望事務的回滾影響客戶端,就應該使用它。另外,當不希望客戶端的回滾影響你的時候,也應該使用這個值。日志記錄是個很好的 例子,即使父事務回滾,你也希望把錯誤情況記錄到日志中,另一方面,日志記錄細小調(diào)試信息的失敗不應該導致回滾整個事務,并且問題應該僅限于日志記錄組件 內(nèi)。
(3 )Supports ,如果某個EJB 組件使用了Supports 事務屬性,則只有調(diào)用它的客戶已經(jīng)啟用了事務時,這一EJB 組件才會運行在事務中。如果客戶并沒有運行在事務中,則EJB 組建也不會運行在事務中。Supports 同Required 事務屬性很相似,但是,Required 要求EJB 組件必須運行在事務中。如果使用Support 事務屬性,EJB 組建很可嫩沒有運行在事務中。
(4 )Mandatory ,Mandatory 事務屬性要求調(diào)用EJB 組件的客戶必須已經(jīng)運行在事務中。如果從非事務性客戶端調(diào)用使用Mandatory 屬性的EJB 方法,那么客戶將接受到系統(tǒng)拋出的javax.ejb.EJBTransactionRequiredException 異常。EJB 組件使用Mandatory 事務屬性是非常安全的,它能夠保證EJB 組建運行在事務中。如果客戶沒有運行在事務中,則不能夠調(diào)用到應用了Mandatory 事務屬性的EJB 組件。但是,Mandatory 事務屬性要求第3 方(及客戶)在調(diào)用EJB 組件前必須啟動了事務。EJB 容器并不會為Mandatory 事務屬性自動啟動新事務,這是同Support 事務屬性的最主要區(qū)別。
(5 )NotSupported ,如果EJB 組件使用了NotSupport 事務屬性,它根本不會參與到事務中。如果調(diào)用者使用相關聯(lián)的事務調(diào)用方法,容器就會暫停事務,調(diào)用方法,然后再方法返回時恢復事務。通常,此屬性只用于非實物性的自動確認模式中,支持JMS 提供者的MDB 。
(6 )Never ,如果EJB 組件使用Never 事務屬性,它就不能夠參與到事務中,而且,如果調(diào)用它的客戶已經(jīng)處于事務中,則容器會將javax.ejb.EJBException 異常拋給客戶。
事務效果圖,其中,T1 和T2 是2 個不同的事務,T1 是客戶請求傳遞的事務,T2 是容器啟動的事務,通過下表,能夠理解各種事務屬性在影響事務長度和范圍方面所起的重要作用。
事務屬性 |
客戶事務 |
EJB 組件事務 |
Required |
無 T1 |
T2 T1 |
RequiresNew |
無 T1 |
T2 T2 |
Supports |
無 T1 |
無 T1 |
Mandatory |
無 T1 |
錯誤 T1 |
NotSupported |
無 T1 |
無 無 |
Never |
無 T1 |
無 錯誤 |