3.事務 CORBA OTS EJB的事務模型與OTS類似。事實上,CORBA兼容的EJB服務器必須提供一個OTS兼容的事務服務。理解OTS如何工作有助於理解EJB中事務的工作方式。 定義事務 一個事務正式地定義了一個原子工作單位。一個事務中可以包含多個操作,當事務終止時,所有執行的操作或者完全執行或者完全廢棄。這稱為提交和回滾。 在數據庫應用中廣泛地使用事務。好的數據庫產品對事務提供很強的支持。一個事務中訪問的記錄在整個事務持續期間保持鎖定狀態。基於數據庫產品在事務開始時可以選定不同的鎖定狀態。選定的鎖定級別應在其它的事務中優化操作的並發訪問時保證數據的完整性。網絡上的事務可能是分布式的,例如客戶端可能在單個事務中訪問兩個不同的數據庫。為了支持分布式事務,大多數事務管理器(包括數據庫)支持兩段提交。在兩段提交協議中,事務管理器在准備提交事務前首先詢問所有的事務參與者的工作是否完成。這是協議的第一階段。一旦每個參與者同意提交,第二階段才會開始。事務管理器發送獨立的提交操作的命令。 OTS中的關鍵部件 為了更好地理解OTS如何工作,我們需要先看看其關鍵部件。以下的部件可以直接地映射到EJB,而理解這些部件如何在OTS中工作能使我們更好地理解EJB中的事務。 ·Control ·terminator ·Coordinator ·Resource ·Synchronization 下圖示出了這些對象中定義的重要方法,以及在事務體系中這些對象的作用。 虛線框內是一個事務。事務中所有的對象都參與了這個事務,提交和回滾對所有的Resource對象都適用。 Control對象代表一個事務。從該對象我們可以得到Coordinator和Terminator 。EJB開發者不會看到Control對象,容器代表bean用Control對象來管理事務。 當一個bean方法返回且該方法在部署描述符中聲明在方法返回前需提交該事務時,容器也用Terminator來提交或回滾事務。提交或回滾事務時,所有事務中的對象都會相應的提交或回滾。 Resource是包含事務狀態的對象。例如,它可能是一個數據庫連接。在這個對象上調用commit()會更新數據庫。一個rollback()調用會恢復該事務開始時通過這個連接對數據作的任何改變。完成提交或回滾後,數據庫中相應的記錄就會解鎖。應用的鎖級別會在部署描述符中指定。這個對象的完全的方法集會顯示這些對象實現了兩段提交協議,使得每一個對象都有權決定整個事務是提交還是回滾。當一個事務完成時,不論是提交還是回滾,都要通知Synchronization對象。與Resource不同,它並不參與兩段提交協議,所以無權表決一個事務應該提交還是回滾。在事務中它扮演一個被動的角色。 Coordinator是使這一切工作起作用的對象。Resource和Synchronization通過該對象注冊到事務中。Bean不直接訪問這個對象。 Transaction-aware objects that are intended for use with EJB will transparently obtain a reference to the current transaction's Coordinator to register itself. 事務和可恢復的對象 在OTS中事務和可恢復的對象不同。這個區別與EJB有關。在CORBAservice? OTS規范中詳細地定義了這些類型,簡單地說,可恢復對象有commit()和rollback()方法,允許事務直接地操縱它自己的狀態和行為。一個事務對象沒有這些方法,不能被事務影響。然而,事務對象有與其關聯的事務,以使分配的可恢復對象(或Resources)與事務對象的當前事務相關聯。一個enterprise bean是一個事務對象的好例子。容器代表bean維護事務。任何bean分配的可恢復對象在容器的幫助下透明地放置在事務中。Bean沒有commit()或rollback()方法,因此事務不能直接操縱bean.讓bean作為一個可恢復的Resource並沒有什麼意義,因為這使得bean開發者必須為每個bean添加額外的代碼,而enterprise bean幾乎沒有內在狀態應該影響一個外部的事務。讓enterprise bean作為可恢復對象的管理者,讓可恢復對象完成這個工作會更好。 注意bean在容器試圖提交或回滾之前可以有權表決回滾一個事務。在EJBContext中Bean可以用Coordinator中的rollback_only()方法作為setRollBackOnly()給事務設置標志,以使事務終止時間到達時請求回滾。還可以通過SessionSynchronization接口通知一個bean有關一個事務的結果。 在部署描述符中指定事務控制 bean的部署描述符包含一個ControlDescriptor對象的數組。每個ControlDescriptor描述了與方法關聯的事務控制。 Bean開發者指定bean方法中的事務控制。部署者在對方法的事務相關行為沒有細致了解的情況下一般不應改變這些值。如下的六個事務控制是在ControlDescriptor類定義的整形常量。除了該類的方法,沒有其它的APIs能訪問它們。Bean本身不訪問事務控制。 Bean本身的方法不能訪問其事務屬性。容器讀取這些控制值來維護bean的相應的事務行為。 ·TX_NOT_SUPPORTED ·TX_SUPPORTS ·TX_REQUIRED ·TX_REQUIRES_NEW ·TX_MANDATORY ·TX_BEAN+NANAGED 你可以通過廠商提供的創建部署描述符的工具來為bean設置合適的ControlDescriptor. TX_NOT_SUPPORTED 該方法不應運行在事務上下文中。如果在一個事務中執行線程,那麼這個事務將掛起直到線程從方法中返回。 TX_SUPPORTS 該方法不需要事務,運行該方法時線程可能有一個活動的事務。 TX_REQUIRED 該方法必須運行在事務中。如果線程已經有一個事務,則這個線程允許進入此方法。如果線程沒有事務,則容器代表線程啟動一個允許線程進入的事務,當線程返回是終止事務。一般應提交事務。如果現成調用 setRollbackOnly()方法,則容器相應地執行一個回滾。 TX-REQUIRED_NEW 不論線程是否有一個事務,容器都會在方法調用期間創建一個事務。當線程返回時,容器提交或回滾這個事務。如果線程有一個進行中的事務,則新事務會掛起直到線程返回或方法的事務終止。 TX_MANDATORY 當調用這個方法時線程必須已經在一個事務中。如果線程沒有事務,則容器會拋出一個例外。 TX_BEAN_MANAGED 這個與上述幾個不同。這種方法表明容器不應在事務管理中起作用。 JTS-Java事務服務 實際上JTS不是一個事務服務--只是底層服務提供者的一層接口。JTS非常簡單,由一個接口和幾個例外組成。從例外列表很容易能看出它類似OTS,雖然它也可以作為其它服務的接口。對於聲明事務控制方式為自管理的bean,可以通過這個接口訪問事務服務。廠商也可以用它來提供對客戶端劃分事務的支持。 如下是UserTransaction接口的定義: public interface Javax.jts.UserTransaction { public void begin() throws IllegalStateException; public void commit() throws TransactionRolledBackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException; Public void rollback() throws SecurityException, IllegalStateException; Public void setRollbackOnly() throws IllegalStateException; public void setTransactionTimeout(int seconds); public int getStatus(); //STATUS_ACTIVE,STATUS_COMMITTING, //STATUS_COMMITTED,STATUS_MARKED_ROLLBACK //STATUS_NO_TRANSACTION,STATUS_PREPARED //STATUS_PREPARING,STATUS_ROLLEDBACK //STATUS_ROLLING_BACK,STATUS_UNKNOWN }