




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
什么是分布式事務?在開始研究如何使用分布式事務開發應用程序之前,讓我們回顧一下什么是分布式事務以及為什么說它們很有用。有幾個術語經常被混淆:事務、分布式事務、兩階段提交(two-phasecommit)、XA事務、事務傳播和CORBAOTS事務。但實際上這些術語的含義各不相同:事務一作為工作的單一邏輯單元而執行的一系列操作,在執行過程中要么所有的操作都被執行,要么一個都不執行(也被稱為本地或簡單事務)。事務經常被描述為ACID-原子性、一致性、隔離性和持久性。為使事務持久,在事務的試驗期所做的變更,最終必須用提交操作作為事務的結尾。如果有任何變更不能被提交,則事務將回滾(rollback),并取消所有的變更,恢復到事務從沒有發生之前的狀態。如果代碼執行的操作決定不進行提交或者不能成功提交,那么它必須回滾該事務以取消這些操作。如果在事務進行期間應用程序崩潰,則在重啟時,事務恢復將回滾該事務。在寫事務中,所有的變更必須全部提交或者全部回滾。在讀事務中,沒有變更需要提交,但是事務會防止對正在被讀取的數據的修改,直到所有的讀操作全部結束。分布式事務一兩個或更多事務資源(比如,兩個單獨的數據庫)之間的ACID事務。為使事務成功提交,所有的獨立資源必須全部成功提交。如果其中的任何一個沒有成功提交,則事務必須在所有的資源中回滾。兩階段提交一一種分兩步提交分布式事務的方法:第1階段,準備每個資源報告是否其已經準備完畢,可以提交--通常通過繼續并保持新數據,但仍然不刪除舊數據。第2階段,提交:如果所有的資源都準備就緒,則全部進行提交--在舊數據刪除且事務不再回滾之后進行。兩階段提交確保了分布式事務也可以始終提交或者始終回滾,即使在事務提交過程中系統的一部分崩潰,也不會受到影響。有許多(但不是全部)分布式事務的實現使用兩階段提交。XA規范--開放組織(OpenGroup)的X/Open分布式事務流程(DTP)模型,它定義了應用程序如何使用事務管理程序跨多個資源管理程序來協調分布式事務。如果事務是通過遵循XA的事務管理程序來進行協調的,則任何遵循XA規范的資源管理程序都可以參與該事務,因此就可以讓不同廠商的事務產品可以共同工作。所有遵循XA的事務都是分布式事務。XA既支持一步提交,也支持兩階段提交。下圖是XA規范,它展示了分布式事務的各部分:X/Open分布式事務(DTP)模型事務傳播一通過將事務上下文作為線程的一部分進行傳遞,以允許多個合作對象參與單個事務。當線程經過合作對象時,事務管理程序使用線程的事務上下文來執行所有的工作。CORBAOTS規范一對象管理組(ObjectManagementGroup)的通用對象請求代理體系結構對象事務服務(CommonObjectRequestBrokerArchitectureObjectTransactionService)--定義遵循規范的流程如何跨多個流程線程將事務上下文從一個流程傳播到另一個流程。這種傳播使得即使分布式對象運行于來自不同廠商的容器中,也可以在單個事務中合作°CORBAOTS規范建立在XA規范的基礎之上。下圖是OTS規范,它展示了包含分布式對象的事務的各部分:對象事務服務(OTS)模型IBM?WebSphere?ApplicationServerV5為其應用程序提供既符合XA規范又符合CORBAOTS規范的事務管理程序。該事務管理程序實現了兩個API,這兩個API是Java?2EnterpriseEdition(J2EE)的一部分--Java事務API(JTA),它提供對Java事務服務(JavaTransactionService,JTS)的簡單訪問。對于任何遵循XA規范的資源,JTA的XA部分都有能力協調用這些資源的事務(通過接口javax.transaction.xa.XAResource)。J2EE中支持XA的兩個資源類型是Java數據庫連接(JavaDatabaseConnectivity,JDBC)API(通過接口javax.sql.XAConnection)和Java消息服務(JavaMessageService,JMS)API(通過接口javax.jms.XAConnection)。當一個容器中的EJB調用另一個容器中的EJB時,事務管理程序將使用CORBAOTS。為什么使用分布式事務?當應用程序需要訪問或更新事務資源中的數據時,它應該(通常是必須)使用事務來進行該項工作。在沒有自動提交的標準JDBC代碼中,應用程序使用一個連接來訪問和更新數據,然后提交該連接以結束這個事務(并啟動另一個事務)。當JMS客戶端發送或接收消息時,消息傳遞提供方使用事務來向目標中添加消息或從目標中刪除消息。JMS客戶端可以任意的顯式控制該事務,比如在同一個消息傳遞系統中,協同處理從一個隊列接收消息和向另一個隊列發送消息。當應用程序有一個單獨的功能需要訪問或更新多個事務資源中的數據時,應該使用分布式事務。您可以在每個資源中使用獨立的簡單事務,但是這種方法很容易出錯。如果一個資源中的事務成功提交,而另一個資源中的事務提交失敗且必須回滾,那么第一個事務將不再回滾,這將使應用程序的狀態不一致。如果一個資源成功提交,但在另一個資源成功提交前系統崩潰,那么也會造成應用程序狀態不一致。哪些功能需要訪問多個事務資源?以下是一些例子:?在數據庫之間移動數據一將數據從一個數據庫移動到另一個數據庫的應用程序需要使用分布式事務。否則,數據可能會重復(如果插入成功但刪除失敗)或丟失(如果刪除成功但插入失敗)。?在數據庫和消息之間移動數據--應用程序需要將數據從JMS消息移動到數據庫表,或者相反。如果不使用分布式事務,數據可能會重復或丟失。?將消息紀錄到數據庫一應用程序也許要使用數據庫來保存“跟蹤紀錄”,“跟蹤紀錄”中記錄了該應用程序與合作伙伴應用程序進行交換的消息。為了讓紀錄保持持久且準確,需要在發送或接收消息的分布式事務中記錄這些消息。?在消息傳遞系統之間移動消息一許多消息傳遞場景包括接收一個消息并發送另一個消息作為結果。當兩個目的地在同一個消息傳遞系統中時,接收和發送可以在一個簡單事務中進行,這是因為它們只涉及單一的事務資源。然而,當從一個消息傳遞系統接收消息,并將消息發送到另一個單獨的消息傳遞系統時,應用程序應該在兩個消息傳遞系統間的分布式事務中執行操作,以確保消息不會重復或丟失。?與企業信息系統(EIS)協同工作--J2EE規范包含J2EE連接器體系結構,該體系結構用于實現適配器以訪問企業信息系統(EIS),比如CICS或SAP。適配器提供的事務支持級別一無、本地或XA--這取決于EIS被賦予的適配能力。如果適配器支持XA事務,應用程序就可以使用分布式事務來協調EIS資源與JDBC和JMS資源。基本上,只要應用程序使用多個事務性持久資源,就需要使用分布式事務。操作多個資源的任何功能都應該使用分布式事務。事務和EJBEnterpriseJavaBeans(EJBs)有許多優點:組件化、遠程調用、安全性、持久性功能、消息傳遞功能等等。盡管這些功能都很有用,但使用EJB的最大好處可能就是事務管理。EJB和容器管理事務(container-managedtransactions,CMTs)使事務管理對于bean開發人員來說實質上是透明的。EJB上的每個公共方法都定義了EJB容器和EJB客戶端之間的事務邊界,并在部署描述符指定該邊界。這種方式的結果是客戶端調用的所有EJB代碼都運行于單個容器管理事務中(直到部署描述符指定另一個),這樣代碼的工作要么全部執行,要么全部回滾。此外,bean開發人員實際上不需要編寫任何用于處理事務的代碼,比如確定何時調用commit()方法以及調用失敗時該如何處理。容器通過事務邊界和部署描述符表示了事務模型,并在運行時控制事務的提交和回滾。即使多個EJB合作執行任務時,EJB容器管理事務也可以工作。一旦線程中的第一個EJB建立了事務上下文,事務容器將使用事務傳播來將該上下文傳遞到合作EJB,這樣所有的工作都在同一事務中執行(直到部署描述符指定另一個)。即使合作EJB存在于不同的容器中,CORBAOTS也可以啟用容器的事務管理程序進行協調,從而使事務跨容器傳播。EJB容器管理事務對控制分布式事務特別有幫助。該方法允許代碼操作多套數據,而不需要關心數據是來自單個資源(需要簡單事務)還是多個資源(需要分布式事務)。應用程序只根據需要來使用EJB操作數據。EJB容器的事務管理程序在運行時確定數據是來自單個資源(這種情況下它使用資源管理程序管理事務),還是來自多個資源(這種情況下使用事務管理程序管理事務,并協同資源管理程序)。不管數據來自于單個還是多個資源,EJB代碼保持不變,而由EJB容器適當的處理事務。回頁首使用分布式事務進行開發現在我們已經審查了想達到什么目標。我們確定了分布式事務是什么、有幫助且必需的場景,以及EJB技術如何使這些場景對bean開發人員大大簡化。現在我們使用WebSphereStudioApplicationDeveloper(以下簡稱ApplicationDeveloper)來創建并運行一個簡單的范例。這些代碼片斷向您展示了如何創建ApplicationDeveloper測試服務器,以及如何為JDBC和JMS配置該服務器。它向您演示了使用特定于本范例的值來填寫特定設置。每個表單前的描述說明了哪些值是適用于所有應用程序的,哪些值是特定于本范例的。本范例也將說明如何為兩個常用JDBC數據庫產品(DB2?和Oracle)配置XA數據源。還將說明如何用XA連接來配置JMS目的地。為開始本范例,我們需要創建一個新的測試服務器。為此,切換到Servers透視圖。從ServerConfiguration視圖的上下文(通過單擊鼠標右鍵)菜單,選擇New=>ServerandServerConfiguration。在創建對話框中,輸入服務器名稱(例如'XAExampleServer”),選擇TestEnvironment(對于本范例,WebSphere5.0版本或WebSphere5.1版本都可以)作為服務器類型,然后單擊finish。創建新服務器和服務器配置對話框配置OracleXA數據源在創建數據源之前,我們將創建JAAS身份驗證條目,以后我們將使該條目關聯到數據源,以便登錄數據庫。在服務器配置編輯器中,切換到Security頁面。在JAASAuthenticationEntries列表中添加一個條目。您的條目必須對您的數據庫有效,如本文所示,它能夠創建表和添加數據。在本范例中,我們將使用一個注冊范例,它是缺省Oracle安裝的一部分。您可以通過特定的安裝來使用不同的注冊。OracleJAAS身份驗證條目設置屬性名稱屬性值是否缺省?AliasScottUserIDscottPasswordtiger添加JAAS身份驗證條目對話框對于本范例,服務器配置必須包含JNDI中注冊的JDBC數據源,比如jdbc/OracleXADS。它是JDBC提供者,并將作為OracleXA數據庫而被訪問。首先,我們需要創建描述如何訪問OracleXA的JDBC提供者。在服務器配置編輯器中,切換到DataSource頁面。在JDBC提供者列表中按下面所示添加一個提供者。名稱可以任選,我們將使用與提供者類型相同的名稱。OracleJDBC提供者設置屬性名稱屬性值是否缺省?JDBCProvidertypeOracleJDBCDriver(XA)NameOracleJDBCDriver(XA)Implementationclassnameoracle.jdbc.xa.client.OracleXADataSourcedefaultClasspath${ORACLE_JDBC_DRIVER_PATH}/ojdbc14.jardefault創建JDBC提供者對話框第二步,創建JDBC數據源以提供對特定OracleXA數據庫的訪問。選擇我們剛剛創建的Oracle提供者,然后用如以下所示的設置添加一個數據源。名稱可以任選。JNDI名是您的代碼用來查找數據源的唯一標識符。本文的范例代碼使用jdbc/OracleXADS作為JNDI名。對于容器管理的身份驗證別名,選擇我們先前創建的JAAS身份驗證條目。URL是所需的資源屬性,它指定訪問數據庫的路徑。OracleJDBC數據源設置屬性名稱屬性值是否缺省?JDBCProvidertypeOracleJDBCDriver(XA),version5.0NameExampleOracleXADataSourceJNDInamejdbc/OracleXADSHelperclasscom.ibm.websphere.rsadapter.OracleDataStoreHelperdefaultAuthenticationaliasScottURLjdbc:oracle:thin:@localhost:1521:example創建JDBC數據源對話框我們剛才創建的JDBC提供者會在特定的目錄中查找它的JAR文件,該目錄通過變量ORACLE_JDBC_DRIVER_PATH指定。該變量必須設置為正確的目錄,但WebSphereStudio并不知道您的Oracle客戶端安裝在哪里,因此您必須指定該目錄。在服務器配置編輯器中,切換到Substitutionvariables頁面。在Node設置下面是已定義變量列表。找到用于Oracle的變量,并將其設置為包含ojdbc14.jar文件的目錄。Oracle定義的變量(對節點)設置屬性名稱屬性值是否缺省?ORACLE_JDBC_DRIVER_PATHC:\oracle\ora92\jdbc\lib
編輯OracleJDBC驅動程序路徑變量對話框現在您已經用OracleXAJDBC數據源配置了服務器。保存服務器配置。盡管您已經用OracleXAJDBC數據源配置了您的測試服務器,但還需要對Oracle數據庫自身進行配置以使其支持XA事務。OracleDBA可以幫助您確定是否需要進一步的配置,并可以幫助您執行這些步驟。在本文的后面,我們將討論如果您的Oracle針對XA進行配置,將會出現什么錯誤,以及如何進行正確的配置。配置DB2XA數據源本范例還包含了DB2XA數據源°DB2數據源的配置設置與Oracle數據源的配置設置很相似。首先,定義一個JAAS標識用于登錄到您的數據庫。在本范例中,我們設置了一個名為DB2的標識。DB2JAAS身份驗證條目設置第二步,我們需要為DB2XA數據源創建一個JDBC提供者。DB2JDBC提供者設置屬性名稱屬性值是否缺省?JDBCProvidertypeDB2UniversalJDBCDriverProvider(XA)NameDB2UniversalJDBCDriverProvider(XA)Implementationcom.ibm.db2.jcc.DB2XADataSourcedefault
classnameClasspath${DB2UNIVERSAL_JDBC_DRIVER_PATH}}/db2jcc.jar${UNIVERSAL_JDBC_DRIVER_PATH}}/db2jcc_license_cu.jar${DB2UNIVERSAL_JDBC_DRIVER_PATH}}/db2jcc_license_cisuz.jardefault第三步,需要使用JNDI名稱jdbc/DB2XADS創建DB2XA數據源。我們將使用在第1步中創建的JAAS標識。盡管Oracle數據源需要URL字符串來訪問數據庫,但DB2數據源只需要數據庫名稱,在本范例中數據庫名稱為“sample”。DB2JDBC數據源設置屬性名稱屬性值是否缺省?JDBCProvidertypeDB2UniversalJDBCDriverProvider(XA),version5.0NameExampleDB2XADataSourceJNDInamejdbc/DB2XADSHelperclasscom.ibm.websphere.rsadapter.DB2UniversalDataStoreHelperdefaultAuthenticationaliasDB2databaseNamesample第四步,需要指定安裝DB2驅動程序的路徑,這是包含了db2jcc.jar文件的目錄。另外,還需要核對數據源類路徑中其他變量的缺省值。DB2定義的變量(對節點)設置屬性名稱屬性值是否缺省?DB2UNIVERSAL_JDBC_DRIVER_PATHC:\db2\SQLLIB\javaUNIVERSAL_JDBC_DRIVER_PATH$(WAS_INSTALL_ROOT}/universalDriver/libdefault現在您已經配置了DB2XA數據源,并將其注冊為jdbc/DB2XADS。保存服務器配置。配置JMS提供者為了演示XA事務,我們還需要嵌入JMS資源。ApplicationDeveloper中內嵌了JMS模擬器,它是一個簡單的JMS資源,但卻包含了全部的XA功能。您的使用DB2或OracleXA的WebSphere應用程序可以使用JMS以外的資源,但本范例需要使用JMS。
在服務器配置編輯器中,切換到JMS頁面。在JMSServerProperties下,添加隊列名XAExampleQ。在JMSProvider下,選擇MQSimulatorforJavaDevelopers。在本范例中,服務器配置必須包括兩個JMS資源:一個名為jms/XAExampleQCF的隊列連接工廠(queueconnectionfactory)和一個名為jms/XAExampleQ的隊列。在服務器配置編輯器的JMS頁面上,在WASQueueConnectionFactories條目列表中,按以下所示添加一個新的隊列連接工廠。確保XA支持被啟用,這是本范例中最重要的一點。WAS隊列連接工廠設置屬性名稱屬性值是否缺省?NameXAExampleQCFJNDINamejms/XAExampleQCFEnableXASupportTrue(checked)default添加WAS隊列連接工廠對話框
在WASQueue條目列表中,用以下設置添加一個新隊列:WAS隊列設置屬性名稱屬性值是否缺省?NameXAExampleQJNDINamejms/XAExampleQ添加WAS隊列對話框保存服務器配置。現在服務器配置已經全部完成。它有一個用于通過XA訪問Oracle的數據源,以及一個使用支持XA事務的隊列連接工廠的JMS隊列。您甚至現在就可以運行服務器。它不包含任何應用程序,但您可以檢驗它是否可以正常啟動,并可以檢驗我們為該服務器配置的JNDC中的對JDBC和JMS資源的綁定。成功的啟動將包含以下特定于JMS以及特定于JDBC的消息:JMSMQJDProvidAMSGS0656I:StartingtheMQJDJMSProviderJMSMQJDProvidAMSGS0650I:MQJDJMSProvideropenforbusinessResourceMgrImIWSVR0049I:BindingXAExampleQCFasjms/XAExampleQCFResourceMgrImIWSVR0049I:BindingXAExampleQasjms/XAExampleQResourceMgrImIWSVR0049I:BindingExampleOracleXADataSourceasjdbc/OracleXADSResourceMgrImIWSVR0049I:BindingExampleDB2XADataSourceasjdbc/DB2XADSCacheServicelIDYNA0048I:WebSphereDynamicCacheinitializedsuccessfully.可選項:導入服務器配置您確實應該按以上描述的方法練習設置服務器配置。但如果您配置不成功,并且希望運行下面將描述的范例應用程序,您可以導入配置。為了開始導入,請下載并解壓縮范例文件。它包含一個名為XAExampleServer.wsc的目錄,這是WebSphereversion5.1服務器配置。在導入服務器配置之前,您首先需要創建一個服務器,這在本文的開始部分就已經描述過。由于該配置適用于5.1版本,因此確保該服務器是WebSphereversion5.1測試環境(在ApplicationDeveloperversion5.1.1中有效)。它還可以幫助您看到服務器列表和配置列表。在Server透視圖的ServerConfiguration視圖中,點擊Menu按鈕選擇View=>Advanced。高級服務器配置視圖菜單ServerGonfipgurat日司況j研目rd頑XAExampleServerAdvanced下一步,通過下列步驟導入服務器配置:從Studio菜單欄中,選擇File=>Import。在Select頁面中打開Import向導。選擇ServerConfiguration并單擊Next。向導切換到它的ImportaServerConfiguration頁面。在ConfigurationName字段中,輸入一個名稱,該名稱必須不同于您剛才創建的服務器名稱,比如“ImportedConfiguration”。Folder字段將是您的服務器項目的缺省名稱,通常名為“Servers”。為ConfigurationType選擇WebSphereversion5.1=>ServerConfiguration。在Location字段中,單擊Browse并選擇您已經下載的XAExampleServer.wsc文件。單擊Finish以導入服務器配置。ServerConfiguration視圖將列出您指定的新配置名稱。導入服務器配置對話框現在我們需要切換到您已經創建好的服務器,這樣就使用您剛才導入的服務器配置。在ServerConfiguration視圖中,選擇服務器,彈出上下文菜單(通過點擊鼠標右鍵),選擇Switchconfiguration,然后選擇您所導入的配置。為您的服務器打開服務器配置編輯器,您將看到它現在已經有了早前描述的JDBC和JMS資源的設置。(如果您沒有看到這些設置,請確保將您的服務器切換到導入的配置。)啟動服務器,您將看到早前描述的服務器啟動日志。回頁首設置范例應用程序本文包括了一個J2EE應用程序范例,您可以下載該范例并導入到ApplicationDeveloper,然后運行。它將使用您早前配置的JDBC和JMS資源來執行一個XA事務。在開始之前,下載并解壓縮范例文件。它包含一個名為XAExampleEAR.ear的EnterpriseArchive(EAR)文件。按照以下步驟將該文件導入到您的WebSphereStudio工作區:從Studio菜單欄中選擇File=>Import。在Select頁面中打開Import向導。選擇EARfile并單擊Next。向導切換到它的EnterpriseApplicationImport頁面。在EARFile字段中,單擊Browse并選擇您所下載的XAExampleEAR.ear文件。項目名稱缺省為XAExampleEAR。單擊Finish以導入該EAR文件。您的工作區現在將包含三個項目,分別是XAExampleEAR、XAExampleEJB和XAExampleWeb。XAExampleEJB項目包含EJB,因此您必須生成它們的部署代碼。選擇XAExampleEJB項目,彈出上下文菜單(通過點擊鼠標右鍵),然后選擇Generate=>DeploymentandRMICcode。使用該對話框為XAExampleSessionbean生成代碼。ApplicationDeveloper將生成一個名稱類似于EJSLocalStatelessXAExampleSession_5a0991c7的新類。這是一個具體類,它與WebSphereApplicationServerEJB容器一同工作,使范例EJB實現EJB規范定義的所有特性。您還必須將EAR項目添加倒測試服務器。這類似于部署EAR,但是更靈活一些,因為當您修改EAR的代碼時,您不必重新部署EAR以使用新代碼。相反,您可以簡單的重啟服務器或者在運行中的服務器內重啟EAR項目并開始測試您對代碼的修改。要將EAR項目添加到測試服務器,請在ServerConfigurations視圖中選擇服務器,彈出上下文菜單(通過點擊鼠標右鍵),然后選擇Addandremoveprojects。在該對話框中,將XAExampleEAR添加到已配置項目列表中。在ServerConfiguration視圖中展開導入的配置,您將看到該EAR成為配置的一部分。下載的范例中還包含一個名為XAExampleDB.sql的文件,它創建了一個名為XA_EXAMPLE的數據庫表。對于Oracle,在SQL*Plus中運行該文件以創建表:SQL>@C:\temp\XAExampleArticle\XAExampleDB.sqlDROPTABLEXA_EXAMPLE*ERRORatline1:ORA-00942:tableorviewdoesnotexistTablecreated.對于DB2,在DB2命令行處理器中運行該文件:C:\db2\SQLLIB\BIN>db2-tvfC:\temp\XAExampleArticle\XAExampleDB.sqlDROPTABLEXA_EXAMPLEDB21034EThecommandwasprocessedasanSQLstatementbecauseitwasnotavalidCommandLineProcessorcommand.DuringSQLprocessingitreturned:SQL0204N"DB2.XA_EXAMPLE"isanundefinedname.SQLSTATE=42704CREATETABLEXA_EXAMPLE(TEXTVARCHAR(256)NOTNULL)DB20000ITheSQLcommandcompletedsuccessfully.范例代碼范例應用程序比較簡單,它由兩個類組成:XAExampleSessionBean--一個執行XA事務的會話EJB。XAExampleServlet--一個調用EJB的servlet。該會話bean的公共方法persistAndSend(String)將參數寫入兩個JDBC表(DB2和Oracle)和JMS消息中。單獨來看這不是一個非常有用的應用程序,但是,由于JDBC和JMS是事務性資源,因此執行所有三個任務是需要XA事務的。分布式(兩階段)事務確保這三個任務可以成功的執行。如果一個任務不能成功提交,其他的任務將回滾,不執行任何任務。這樣就維護了兩個資源之間的一致性。publicvoidpersistAndSend(Stringdata)throwsException(try(DataSourceoracleDS=getDataSource("java:comp/env/jdbc/OracleXADS");persist(data,oracleDS);DataSourcedb2DS=getDataSource("java:comp/env/jdbc/DB2XADS");persist(data,db2DS);QueueConnectionFactoryfactory=getQueueConnectionFactory(〃java:comp/env/jms/XAExampleQCF〃);Queuequeue=getQueue(〃java:comp/env/jms/XAExampleQ〃);send(data,factory,queue);}catch(Exceptione)(e.printStackTrace();this.getSessionContext().setRollbackOnly();throwe;}該方法執行以下三個步驟:使用名為jdbc/OracleXADS的數據源保持數據。使用名為jdbc/DB2XADS的數據源保持數據。將JMS消息中的數據發送到名為jms/XAExampleQ的隊列。如果發生任何錯誤,批處理塊將捕捉該異常,將事務標記為回滾,并重新拋出該異常。為了代碼的完整性,以下列出了實現該會話bean的其余代碼:privatevoidpersist(Stringdata,DataSourcedatasource)throwsSQLException(System.out.println("Addinganewdatabaserowcontaining:"+data);Connectionconnection=null;try(connection=datasource.getConnection();PreparedStatementstatement=connection.prepareStatement("INSERTINTOXA_EXAMPLE(TEXT)VALUES(?)");statement.setString(1,data);statement.execute();System.out.println("Successfullyaddedrow:"+data);}finally(if(connection!=null)connection.close();privatevoidsend(Stringdata,QueueConnectionFactoryfactory,Queuequeue)throwsJMSException(System.out.println("Sendingamessagecontaining:"+data);QueueConnectionconnection=null;try(connection=factory.createQueueConnection();QueueSessionsession=connection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);QueueSendersender=session.createSender(queue);TextMessagemessage=session.createTextMessage(data);sender.send(message);System.out.println("Successfullysentmessage:"+data);}finally(if(connection!=null)connection.close();}}privateDataSourcegetDataSource(StringjndiName)throwsNamingException(return(DataSource)this.getJNDIObject(jndiName);}privateQueueConnectionFactorygetQueueConnectionFactory(StringjndiName)throwsNamingException(return(QueueConnectionFactory)this.getJNDIObject(jndiName);}privateQueuegetQueue(StringjndiName)throwsNamingException(return(Queue)this.getJNDIObject(jndiName);}privateObjectgetJNDIObject(StringjndiName)throwsNamingException(Contextroot=newInitialContext();returnroot.lookup(jndiName);}這是用于使用JDBC和JMS的標準代碼。甚至沒有任何代碼用于定義事務或者將事務變為XA。但由于WebSphereApplicationServer的EJB容器將這些代碼作為單獨的公共EJB方法來調用,所以容器會在事務中自動運行這些代碼。容器將正常使用簡單(單階段)事務,但當第二個事務資源更新時,容器將自動檢測,并將簡單事務轉換為XA事務。作為該工作的一部分,容器將通知資源并為其協調XA事務,讓這些資源參與該事務。所有這些行為都是自動完成的,不需要開發人員編寫任何額外的代碼,而僅僅通過實現EJB中的代碼就可以完成。回頁首運行范例應用程序當您閱讀本文時,最好應該在ApplicationDeveloper中執行這些步驟。如果您是這樣做的,那么現在您已經配置了一個測試服務器并安裝了范例EAR。現在可以啟動服務器以運行該應用程序。在Server透視圖中,進入Servers視圖。選擇您的服務器并單擊Start運行它。如果服務器正確運行,您將在控制臺看到類似于以下紀錄的啟動日志:JMSMQJDProvidAMSGS0656I:StartingtheMQJDJMSProviderJMSMQJDProvidAMSGS0650I:MQJDJMSProvideropenforbusinessResourceMgrImIWSVR0049I:BindingXAExampleQCFasjms/XAExampleQCFResourceMgrImIWSVR0049I:BindingXAExampleQasjms/XAExampleQResourceMgrImIWSVR0049I:BindingExampleOracleXADataSourceasjdbc/OracleXADSResourceMgrImIWSVR0049I:BindingExampleDB2XADataSourceasjdbc/DB2XADSCacheServiceIIDYNA0048I:WebSphereDynamicCacheinitializedsuccessfully.???ApplicationMgAWSVR0200I:Startingapplication:XAExampleEAREJBContainerIIWSVR0207I:PreparingtostartEJBjar:XAExampleEJB.jarEJBContainerIIWSVR0037I:StartingEJBjar:XAExampleEJB.jarWebContainerASRVE0169I:LoadingWebModule:XAExampleWeb.WebGroupISRVE0180I:[XAExampleWeb][/XAExampleWeb][Servlet.LOG]:JSP1.2Processor:initWebGroupISRVE0180I:[XAExampleWeb][/XAExampleWeb][Servlet.LOG]:SimpleFileServlet:initWebGroupISRVE0180I:[XAExampleWeb][/XAExampleWeb][Servlet.LOG]:InvokerServlet:initApplicationMgAWSVR0221I:Applicationstarted:XAExampleEAR現在我們可以運行范例應用程序。在您的web瀏覽器中,調用這個URL:http://localhost:9080/XAExampleWeb/XAExampleServlet?data=hello%20world這將使用一個參數調用我們的XAExampleServletservlet,該參數的名稱為data,值為“helloworld”。如果一切運行正常,瀏覽器中將會顯示以下結果:Justpersistedandsentdata:helloworld同樣,在服務器控制臺,您將看到以下一些狀態消息:SystemOutOAddinganewdatabaserowcontaining:helloworldSystemOutOSuccessfullyaddedrow:helloworldSystemOutOAddinganewdatabaserowcontaining:helloworldSystemOutOSuccessfullyaddedrow:helloworldSystemOutOSendingamessagecontaining:helloworldSystemOutOSuccessfullysentmessage:helloworld如果所有這些工作都完成,恭喜您,您已經成功運行了一個使用了XA事務的應用程序,該XA事務跨越JDBC和JMS資源。SystemOut范例應用程序的故障診斷有幾個潛在的問題可能導致范例的運行不成功。其中兩個是部署范例時的常見錯誤,這很容易改正。另外兩個是關于Oracle數據庫中的配置問題,這需要OracleDBA來修改。以下部分列出了可能出現的問題,它說明了ApplicationDeveloper控制臺顯示的異常,給出了關于為什么會發生問題的簡短描述,并說明了如何修改每個問題。ClassNotFoundException:EJSStatelessXAExampleSessionHomeBean啟動服務器時,如果應用程序成功啟動,您將得到這些消息:ApplicationMgAWSVR0200I:Startingapplication:XAExampleEAREJBContainerIIWSVR0207I:PreparingtostartEJBjar:XAExampleEJB.jarEJBContainerIIWSVR0037I:StartingEJBjar:XAExampleEJB.jarWebContainerASRVE0169I:LoadingWebModule:XAExampleWeb.WebGroupISRVE0180I:[XAExampleWeb][/XAExampleWeb][Servlet.LOG]:JSP1.2Processor:initWebGroupISRVE0180I:[XAExampleWeb][/XAExampleWeb][Servlet.LOG]:SimpleFileServlet:initWebGroupISRVE0180I:[XAExampleWeb][/XAExampleWeb][Servlet.LOG]:InvokerServlet:initApplicationMgAWSVR0221I:Applicationstarted:XAExampleEAR然而,您也可能會得到以下錯誤:ApplicationMgAWSVR0200I:Startingapplication:XAExampleEAREJBContainerIIWSVR0207I:PreparingtostartEJBjar:XAExampleEJB.jarBeanMetaDataECNTR0075E:Theuser-providedclass"com.ibm.example.xa.EJSStatelessXAExampleSessionHomeBean_5a0991c7"neededbytheEnterpriseBeancouldnotbefoundorloaded.EJBContainerIEWSVR0209E:UnabletoprepareEJBjarXAExampleEJB.jar[ponent.DeployedModuleImpl],enterprisebeancom.ibm.etools.ejb.impl.SessionImpl(XAExampleSession)(transactionType:Container,sessionType:Stateless)java.lang.ClassNotFoundException:com.ibm.example.xa.EJSStatelessXAExampleSessionHomeBean_5a0991c7atcom.ibm.ws.classloader.CompoundClassLoader.findClass(CompoundClassLoader.java:351)atcom.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:261)atjava.lang.ClassLoader.loadClass(ClassLoader.java(CompiledCode))atcom.ibm.ejs.container.BeanMetaData.loadExistedClass(BeanMetaData.java:2573)atcom.ibm.ejs.container.BeanMetaData.<init>(BeanMetaData.java:888)ponent.EJBContainerImpl.createBeanMetaData(EJBContainerImpl.java:980)...DeployedAppliWWSVR0206E:Module,XAExampleEJB.jar,ofapplication,XAExampleEAR.ear/deployments/XAExampleEAR,failedtostartApplicationMgWWSVR0101W:Anerroroccurredstarting,XAExampleEARApplicationMgAWSVR0217I:Stoppingapplication:XAExampleEARApplicationMgAWSVR0220I:Applicationstopped:XAExampleEAR該錯誤是ClassNotFoundException,缺少的類是com.ibm.example.xa.EJSStatelessXAExampleSessionHomeBean_5a0991c7。該錯誤發生在試圖啟動EJBjarXAExampleEJB.jar的時候。該錯誤指出了您沒有生成EJB代碼,因此容器無法為XAExampleSessionbean找到所生成的Home類。要修改該問題,請先在指定的EJB項目中為所有的bean生成DeploymentandRMICcode,然后重新啟動服務器。SQLException:Tableorviewdoesnotexist在第一次運行范例時,您可能會得到以下錯誤:WSRdbDataSourIDSRA8203I:Databaseproductname:OracleWSRdbDataSourIDSRA8204I:Databaseproductversion:PersonalOracle9iRelease.0-ProductionWiththePartitioning,OLAPandOracleDataMiningoptionsJServerRelease.0-ProductionWSRdbDataSourIDSRA8205I:JDBCdrivername:OracleJDBCdriverWSRdbDataSourIDSRA8206I:JDBCdriverversion:.0WebGroupESRVE0026E:[ServletError]-[ORA-00942:tableorviewdoesnotexist]:java.sql.SQLException:ORA-00942:tableorviewdoesnotexistatoracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)atoracle.jdbc.ttc7.TTIcessError(TTIoer.java:289)atoracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)atoracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)atoracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1093)atoracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2047)atoracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1940)atoracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2709)atoracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)atoracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:656)atcom.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.execute(WSJdbcPreparedStatement.java:386)atcom.ibm.example.xa.XAExampleSessionBean.persist(XAExampleSessionBean.java:45)atcom.ibm.example.xa.XAExampleSessionBean.persistAndSend(XAExampleSessionBean.java:30)atcom.ibm.example.xa.EJSLocalStatelessXAExampleSession_5a0991c7.persistAndSend(EJSLocalStatelessXAExampleSession_5a0991c7.java:23)atXAExampleServlet.persistAndSend(XAExampleServlet.java:44)atXAExampleServlet.doGet(XAExampleServlet.java:28)atjavax.servlet.http.HttpServlet.service(HttpServlet.java:740)atjavax.servlet.http.HttpServlet.service(HttpServlet.java:853)該錯誤是SQLException,錯誤代碼為ORA-00942。很顯然,是因為期望的數據庫表或視圖不存在。但是,該錯誤沒有說明具體是哪個表或視圖未找到。棧跟蹤顯示該錯誤發生在一XAExampleSessionBean.persist方法中,它位于.java文件的第45行。點擊那個棧跟蹤行,編輯器將進入該代碼的execute行:PreparedStatementstatement=connection.prepareStatement("INSERTINTOXA_EXAMPLEVALUES(?)");statement.setString(1,data);statement.execute();該問題發生在向XA_EXAMPLE表中插入紀錄的時候。這說明您沒有運行創建數據庫表的SQL文件。要修改該問題,請運行SQL文件:SQL>@C:\workspace\XAExampleEJB\XAExampleDB.sql現在重新運行范例。OracleXAException:XAER_RMERR(InternalXAError)在第一次運行范例時,您可能會得到以下錯誤:WSRdbDataSourIDSRA8203I:Databaseproductname:OracleWSRdbDataSourIDSRA8204I:Databaseproductversion:PersonalOracle9iRelease.0-ProductionWiththePartitioning,OLAPandOracleDataMiningoptionsJServerRelease.0-ProductionWSRdbDataSourIDSRA8205I:JDBCdrivername:OracleJDBCdriverWSRdbDataSourIDSRA8206I:JDBCdriverversion:.0WSRdbXaResourEDSRA0304E:XAExceptionoccurred.XAExceptioncontentsanddetailsare:TheXAErroris:-3TheXAErrormessageis:Aresourcemanagererrorhasoccurredinthetransactionbranch.TheOracleErrorcodeis:65535TheOracleErrormessageis:InternalXAErrorThecauseis:null.WSRdbXaResourEDSRA0302E:XAExceptionoccurred.Errorcodeis:XAER_RMERR.Exceptionis:<null>RegisteredResEWTRN0078E:Anattemptbythetransactionmanagertocallstartonatransactionalresourcehasresultedinanerror.TheerrorcodewasXAER_RMERR.Theexceptionstacktracefollows:oracle.jdbc.xa.OracleXAExceptionatoracle.jdbc.xa.OracleXAResource.checkError(OracleXAResource.java:1157)atoracle.jdbc.xa.client.OracleXAResource.start(OracleXAResource.java:295)atcom.ibm.ws.rsadapter.spi.WSRdbXaResourceImpl.start(WSRdbXaResourceImpl.java:927)atcom.ibm.ejs.j2c.XATransactionWrapper.start(XATransactionWrapper.java:1267)atcom.ibm.ws.Transaction.JTA.JTAResourceBase.start(JTAResourceBase.java:164)atcom.ibm.ws.Transaction.JTA.RegisteredResources.startRes(RegisteredResources.java:389)atcom.ibm.ws.Transaction.JTA.TransactionImpl.enlistResource(TransactionImpl.java:1903)atcom.ibm.ws.Transaction.JTA.TranManagerSet.enlist(TranManagerSet.java:494)該錯誤是因為事務管理程序不能將事務轉換為XA事務。Oracle明確的返回錯誤XAER_RMERR,錯誤代碼編號為65535。ORA-65535不是一個有效錯誤代碼,并且XAER_RMERR實質上意味著XA發生了某些錯誤。這說明您的Oracle數據庫沒有被配置為支持XA事務。因此,當WebSphereApplicationServer事務管理程序命令Oracle事務管理程序參與這個XA事務時,Oracle拒絕該命令并拋出這個異常。解決方法是運行Oracle安裝中包含的兩個腳本。這很可能需要通過您的OracleDBA來執行,您必須以SYSOPER或SYSDBA身份登錄到Oracle,以擁有足夠的權限來運行這些腳本。這些腳本是:directory:<ORACLE_HOME>\javavm\installofile:initxa.sqlofile:initjvm.sqlinitxa.sql腳本配置XA數據庫。一旦它成功運行,您的數據庫就被配置為XA。該腳本在您第一次運行的時候可能成功。不幸的是,由于一些數據庫的內存空間太小,該腳本也可能無法成功運行。為修改該問題,運行initjvm.sql腳本。它可能也會運行失敗,但是在失敗時,該腳本會說明哪個參數需要調整。參數被保存在該文件中:directory:<ORACLE_HOME>\databaseo
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 木質樂器制作工藝傳承考核試卷
- 票務代理行程規劃與咨詢考核試卷
- 電池制造過程中的市場趨勢分析考核試卷
- 木材的天然防腐和抗菌性能考核試卷
- 植物油加工過程中的副產物利用策略考核試卷
- 電視接收設備的智能廣告投放系統考核試卷
- 泵的耐高溫材料與涂層技術考核試卷
- 有機化學原料的可持續采購策略考核試卷
- 廈門城市職業學院《醫學成像原理與圖像處理》2023-2024學年第二學期期末試卷
- 萍鄉衛生職業學院《文化產業項目策劃》2023-2024學年第二學期期末試卷
- 隱私安全與用戶滿意度關系-洞察分析
- 心理健康C證面試15題
- DB33T 2202-2019 公安警察院校警務化管理規范
- 2025湖南長沙水業集團限公司招聘35人高頻重點提升(共500題)附帶答案詳解
- 2024江蘇無錫江陰公用事業集團限公司招聘1人易考易錯模擬試題(共500題)試卷后附參考答案
- 人教版高中物理《圓周運動》
- 防滲漏工程施工指引
- 物業承接查驗標準(全面)
- 金融借款合同訴訟
- 延長石油題庫
- 湖南長沙民政局離婚協議書范本
評論
0/150
提交評論