http://zh.objectweb.org/JOnAS/gb/PG_Transaction.html
事務(wù)處理行為
面向的讀者和內(nèi)容提要
本文面向的讀者主要是企業(yè)bean的提供者,例如負(fù)責(zé)在服務(wù)器端開(kāi)發(fā)組件的程序員。本文解釋了如何定義EJB應(yīng)用程序的事務(wù)處理.
以下是本文的內(nèi)容提要:
-
面向的讀者和本文的內(nèi)容提要
-
聲明性的事務(wù)管理
-
BEAN管理的事務(wù)
-
分布事務(wù)管理
聲明性的事務(wù)管理
在容器管理事務(wù)這種事務(wù)管理方式的情況下,企業(yè)BEAN的事務(wù)處理行為是在配置時(shí)被定義的,具體體現(xiàn)在標(biāo)準(zhǔn)部署描述符文件中的集成描述符元素( assembly-descriptor element)部分中. 在配置時(shí)我們可以為同一BEAN中所有的方法(methods)同時(shí)定義一個(gè)共通的事務(wù)處理行為,也可以為每個(gè)方法( methods )分別定義不同的事務(wù)處理行為 . 我們通過(guò)指定事務(wù)屬性來(lái)配置事務(wù)的行為.事務(wù)的屬性有如下幾種:
-
NotSupported:如果該方法是在一個(gè)事務(wù)上下文中被調(diào)用,那么該方法執(zhí)行過(guò)程中,該事務(wù)將被掛起.
-
Required:如果該方法是在一個(gè)事務(wù)上下文中被調(diào)用,該方法在該事務(wù)上下文中執(zhí)行.否則(該方法不在一個(gè)事務(wù)上下文中被調(diào)用),在該方法執(zhí)行前,容器將自動(dòng)生成一個(gè)新的事務(wù),隨后該方法在新的事務(wù)上下文中執(zhí)行,并且在該方法結(jié)束時(shí),容器將自動(dòng)提交這個(gè)被自動(dòng)生成新的事務(wù).
-
RequiresNew:該方法總是要求在一個(gè)新的事務(wù)上下文中執(zhí)行.在該方法執(zhí)行前,容器將自動(dòng)生成一個(gè)新的事務(wù),并且在該方法結(jié)束返回時(shí),容器將自動(dòng)提交這個(gè)被自動(dòng)生成的新事務(wù).如果該方法是在一個(gè)事務(wù)上下文中被調(diào)用,那么新的事務(wù)開(kāi)始時(shí),該事務(wù)將被掛起,并且新事務(wù)結(jié)束后,該事務(wù)將重啟.
-
Mandatory:該方法總是要求在一個(gè)事務(wù)上下文中被調(diào)用.否則,容器將拋出 TransactionRequired 例外.
-
Supports:該方法如果在一個(gè)事務(wù)上下文中被調(diào)用,那么該方法將在該事務(wù)上下文中執(zhí)行.如果該方法的調(diào)用者不處在事務(wù)上下文中,那么該方法也就不在任何事務(wù)上下文中執(zhí)行.
-
Never:該方法要求該方法的調(diào)用者不能處在事務(wù)上下文中.否則,容器將拋出 RemoteException 例外.
表格說(shuō)明如下:
事務(wù)屬性 |
調(diào)用者事務(wù) |
企業(yè)BEAN方法(METHOD)的事務(wù) |
NotSupported |
- T1 |
- - |
Required |
- T1 |
T2 T1 |
RequiresNew |
- T1 |
T2 T2 |
Mandatory |
- T1 |
錯(cuò)誤 T1 |
Supports |
- T1 |
- T1 |
Nervere |
- T1 |
- 錯(cuò)誤 |
根據(jù)EJB規(guī)范書(shū)要求,事務(wù)屬性在部署描述符的集成描述符(assembly - descriptor)中設(shè)定,例如:
<assembly-descriptor> <container-transaction> <method> <ejb-name>AccountImpl</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Supports</trans-attribute> </container-transaction> <container-transaction> <method> <ejb-name>AccountImpl</ejb-name> <method-name>getBalance</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> <container-transaction> <method> <ejb-name>AccountImpl</ejb-name> <method-name>setBalance</method-name> </method> <trans-attribute>Mandatory</trans-attribute> </container-transaction> </assembly-descriptor>
在本例中,對(duì)于AccountImpl bean的所有沒(méi)有用container-transaction元素作明確指定的方法, 使用缺省事務(wù)屬性Supports(匹配符*指定缺省事務(wù)屬性,適用于該BEAN所有方法( method )).并且明確指定getBalance 和 setBalance 方法的事務(wù)屬性分別是 Required 和 Mandatory (通過(guò)給定特定的 方法method名).
BEAN管理的事務(wù)
對(duì)于自己管理自己事務(wù)的BEAN,必須在標(biāo)準(zhǔn)部署描述符中設(shè)定其對(duì)應(yīng)的 transaction-type元素.例如下:
<transaction-type>Bean</transaction-type>
對(duì)于BEAN自己管理的事務(wù),BEAN程序員應(yīng)該使用javax.transaction.UserTransaction來(lái)界定事務(wù)邊界.該接口(interface)javax.transaction.UserTransaction由EJB服務(wù)器在服務(wù)器內(nèi)部一個(gè)對(duì)象上實(shí)現(xiàn).可以通過(guò)調(diào)用EJBContext.getUserTransaction()來(lái)獲得該接口(這兒的EJBContext根據(jù)bean的種類session BEAN或entity bean的不同而不同, 在session bean 中 EJBContext指 SessionContext,而在 entity bean EJBContext指 EntityContext ).下面的就是一個(gè)例子,在 session bean的"doTxJob" 方法中界定事務(wù)邊界; UserTransaction 對(duì)象(接口)通過(guò) sessionContext對(duì)象獲取.其中sessionContext對(duì)象在BEAN初始化方法 setSessionContext(BEAN初始化時(shí)自動(dòng)被EJBserver調(diào)用)中作為參數(shù)傳遞過(guò)來(lái).(這意味著B(niǎo)EAN程序員應(yīng)該在setSessionContext中將該 sessionContext對(duì)象保存在BEAN的變量中).(參考 example of the session bean).
public void doTxJob() throws RemoteException { UserTransaction ut = sessionContext.getUserTransaction(); ut.begin(); ... // transactional operations ut.commit(); }
另一個(gè)獲得接口 UserTransaction 的方法是用 JNDI ,即在初始化上下文中通過(guò)使用 java:comp/UserTransaction名字來(lái)獲取.
分布事務(wù)管理
正如前面部分所講,一個(gè)應(yīng)用程序的事務(wù)行為可以通過(guò)聲明的方式來(lái)定義,也可以由BEAN或BEAN的調(diào)用者分別,或BEAN和BEAN的調(diào)用者協(xié)助,用編程的方式在代碼中指定(界定事務(wù)邊界).不管在哪中情況下,事務(wù)的分布特性這方面,無(wú)論對(duì)BEAN提供者(bean provider) 還是對(duì)應(yīng)用集成商(application assembler.)來(lái)說(shuō)都是完全透明的.這意味著一個(gè)事務(wù)可能有多個(gè)在不同的EJB服務(wù)器上的BEAN參與,而平臺(tái)應(yīng)該自己從全局角度管理分布事務(wù).平臺(tái)在多個(gè)不同的服務(wù)器間使用兩相提交協(xié)議(two phase commit )來(lái)管理分布事務(wù),從而B(niǎo)EAN程序員不用考慮事務(wù)的分布特性這方面.
在 been已經(jīng)開(kāi)發(fā)完成,并且應(yīng)用集成結(jié)束后,部署人員 (deployer)或管理員( administrator )也可以將不同的BEAN配置分布在同一或多個(gè)不同的機(jī)器上的同一或多個(gè)不同的EJB服務(wù)器里.
這種配置過(guò)程可以在不涉及到代碼的變動(dòng)或部署描述符的修改的情況下完成.The distributed configuration is specified at launch time: in the environment properties of an EJB server, you may specify分布事務(wù)的配置是在EJB服務(wù)器啟動(dòng)時(shí)進(jìn)行進(jìn)行:所以分布事務(wù)的配置在EJB服務(wù)器的環(huán)境配置文件中設(shè)定.設(shè)定如下:
-
EJB服務(wù)器將管理哪些企業(yè)BEAN
-
指定是否在該EJB服務(wù)器的JVM內(nèi)同時(shí)啟動(dòng)一個(gè)Java Transaction Monitor(JTM).
這須通過(guò)設(shè)定環(huán)境配置文件 jonas.properties 里的jonas.service.ejb.descriptors 和 jonas.service.jtm.remote項(xiàng)來(lái)完成.前一個(gè)列出該EJB服務(wù)器中管理的所有企業(yè)BEAN(通過(guò)指定部署描述符文件名或ejb-jar文件名),后一個(gè)設(shè)定Java Transaction Monitor(JTM)啟動(dòng)模式:
-
如果設(shè)為true,那么JTM使用遠(yuǎn)程方式,即在該EJB服務(wù)器啟動(dòng)前,必須在另一個(gè)JVM中已經(jīng)啟動(dòng)JTM
-
if set to false, the JTM is local, i.e. it will run into the same JVM as the EJB Server. 如果設(shè)為false,那么JTM使用本地方式,即該EJB服務(wù)器的JVM中同時(shí)啟動(dòng)一個(gè)JTM
例如:
jonas.service.ejb.descriptors Bean1.xml, Bean2.xml jonas.service.jtm.remote false
JTM可運(yùn)行在單獨(dú)的JVM中,而不必一定運(yùn)行于某個(gè)EJB服務(wù)器內(nèi).在這種情況下,可以如下命令文單獨(dú)啟動(dòng)JTM:
TMServer
通過(guò)這種靈活的配置方式,就可根據(jù)資源(CPU或數(shù)據(jù)源)的具體情況而采用不同的配置,從而得到最佳的系統(tǒng)性能.
如下例圖是針對(duì)三個(gè)企業(yè)BEAN而采用四種不同配置,
-
第1種情況: 三個(gè)企業(yè)BEAN B1, B2 and B3 分布在同一個(gè)EJB服務(wù)器內(nèi),EJB服務(wù)器內(nèi)同時(shí)啟動(dòng)了一個(gè)Java Transaction Monitor.
-
第2種情況: 三個(gè)企業(yè)BEAN分別分布在不同的EJB服務(wù)器內(nèi),其中有只有一個(gè)EJB服務(wù)器內(nèi)啟動(dòng)了一個(gè)Java Transaction Monitor,用于管理全局分布事務(wù).
-
第3種情況:三個(gè)企業(yè)BEAN分別分布在不同的EJB服務(wù)器內(nèi),JTM運(yùn)行在每個(gè)單獨(dú)的JVM中.
-
第4種情況:三個(gè)企業(yè)BEAN分別分布在不同的EJB服務(wù)器內(nèi). 每個(gè)EJB服務(wù)器內(nèi)啟動(dòng)了一個(gè)Java Transaction Monitor. 其中一個(gè)作為主監(jiān)視器( master monitor),另外兩個(gè)為附屬監(jiān)視器( slaves. )
這些不同的配置情況可通過(guò)配置EJB 服務(wù)器對(duì)應(yīng)的環(huán)境屬性配置文件,再啟動(dòng) EJB 服務(wù)器來(lái)實(shí)現(xiàn),有些情況下也要啟動(dòng)JTM(第3種情況).基本原則是應(yīng)該根據(jù)資源的位置和負(fù)載均衡來(lái)作出合適的選擇.以下幾點(diǎn)說(shuō)明,以供參考:
-
如果企業(yè)BEAN要求運(yùn)行于同一臺(tái)機(jī)器,并且要求相同的EJB服務(wù)器配置,第1種情況應(yīng)該是最佳選擇.
-
如果企業(yè)BEAN要求運(yùn)行于不同機(jī)器,那么第4種情況應(yīng)該是最佳選擇.因?yàn)樵谶@種情況下,本地方式的事務(wù)管理更加合適.
-
如果企業(yè)BEAN要求運(yùn)行于同一臺(tái)機(jī)器,而要求不同的EJB服務(wù)器配置,第2種情況應(yīng)該是好的選擇.