Spring JTA應用之JOTM配置

          原文地址:http://tom-duan.javaeye.com/blog/147594

          JOTM(Java Open Transaction Manager)是ObjectWeb的一個開源JTA實現,本身也是開源應用程序服務器JOnAS(Java Open Application Server)的一部分,為其提供JTA分布式事務的功能。Spring對JOTM提供了較好的支持,提供了一個org.springframework.transaction.jta.JotmFactoryBean的支持類,在Spring2.0中也包含了JOTM相關的一些library。

          jotm的下載地址為http://jotm.objectweb.org,最新版本為2.0.10.

          下載完成后解壓縮,然后打開jotm下面conf文件夾,拷貝carol.properties文件到classpath中,并修改這個文件如下
          carol.properties
          Java代碼
          1. #?do?not?use?CAROL?JNDI?wrapper??? ??
          2. carol.start.jndi=false??? ??
          3. ??? ??
          4. #?do?not?start?a?name?server??? ??
          5. carol.start.ns=false??? ??
          6. ??? ??
          7. #?Naming?Factory ??
          8. carol.jndi.java.naming.factory.url.pkgs=org.apache.naming??

          上面配置文件的目的是不使用JNDI的方式來加載JOTM的配置,當然也可以根據需要選擇其它的一些配置,例如JTOM所提供的默認配置。

          然后開始在Spring上下文中配置JOTM,在classpath中建立一個ApplicationContext-jotm.xml,配置如下

          ApplicationContext-jotm.xml
          Java代碼
          1. <?xml?version="1.0"?encoding="UTF-8"?> ??
          2. <beans?xmlns="http://www.springframework.org/schema/beans"??
          3. ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
          4. ????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> ??
          5. ??
          6. ????<bean?id="jotm"?class="org.springframework.transaction.jta.JotmFactoryBean"/> ??
          7. ???? ??
          8. ????<bean?id="txManager"?class="org.springframework.transaction.jta.JtaTransactionManager"> ??
          9. ????????<property?name="userTransaction"?ref="jotm"?/> ??
          10. ????</bean> ??
          11. ??
          12. ????<bean?id="ds1"?class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"?destroy-method="shutdown"> ??
          13. ????????<property?name="dataSource"> ??
          14. ????????????<bean?class="org.enhydra.jdbc.standard.StandardXADataSource"?destroy-method="shutdown"> ??
          15. ????????????????<property?name="transactionManager"?ref="jotm"?/> ??
          16. ????????????????<property?name="driverName"?value="com.mysql.jdbc.Driver"?/> ??
          17. ????????????????<property?name="url"?value="jdbc:MySQL://localhost:3306/test"?/> ??
          18. ????????????</bean> ??
          19. ????????</property> ??
          20. ????????<property?name="user"?value="root"?/> ??
          21. ????????<property?name="password"?value="admin"?/> ??
          22. ????</bean> ??
          23. ???? ??
          24. ????<bean?id="ds2"?class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"?destroy-method="shutdown"> ??
          25. ????????<property?name="dataSource"> ??
          26. ????????????<bean?class="org.enhydra.jdbc.standard.StandardXADataSource"?destroy-method="shutdown"> ??
          27. ????????????????<property?name="transactionManager"?ref="jotm"?/> ??
          28. ????????????????<property?name="driverName"?value="com.mysql.jdbc.Driver"?/> ??
          29. ????????????????<property?name="url"?value="jdbc:MySQL://localhost:3306/test2"?/> ??
          30. ????????????</bean> ??
          31. ????????</property> ??
          32. ????????<property?name="user"?value="root"?/> ??
          33. ????????<property?name="password"?value="admin"?/> ??
          34. ????</bean> ??
          35. ??
          36. ????<bean?id="template1"?class="org.springframework.jdbc.core.JdbcTemplate"> ??
          37. ????????<property?name="dataSource"?ref="ds1"?/> ??
          38. ????</bean> ??
          39. ???? ??
          40. ????<bean?id="template2"?class="org.springframework.jdbc.core.JdbcTemplate"> ??
          41. ????????<property?name="dataSource"?ref="ds2"?/> ??
          42. ????</bean> ??
          43. ???? ??
          44. ????<bean?id="dao1"?class="com.xa.dao.UserDao1"> ??
          45. ????????<property?name="jdbcTemplate"> ??
          46. ????????????<ref?bean="template1"></ref> ??
          47. ????????</property> ??
          48. ????</bean> ??
          49. ???? ??
          50. ????<bean?id="dao2"?class="com.xa.dao.UserDao2"> ??
          51. ????????<property?name="jdbcTemplate"> ??
          52. ????????????<ref?bean="template2"></ref> ??
          53. ????????</property> ??
          54. ????</bean> ??
          55. ???? ??
          56. ????<bean?id="userServiceTarget"?class="com.xa.service.UserServiceImpl"> ??
          57. ????????<property?name="dao1"?ref="dao1"/> ??
          58. ????????<property?name="dao2"?ref="dao2"/> ??
          59. ????</bean> ??
          60. ??
          61. ??
          62. ????<bean?id="userTest"?class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">???? ??
          63. ????????<property?name="transactionManager"> ??
          64. ????????????<ref?bean="txManager"/> ??
          65. ????????</property>???? ??
          66. ????????<property?name="target"> ??
          67. ????????????<ref?bean="userServiceTarget"/> ??
          68. ????????</property> ??
          69. ????????<property?name="transactionAttributes">???????? ??
          70. ????????????<props> ??
          71. ????????????????<prop?key="insert*">PROPAGATION_REQUIRED,-Exception</prop>???????????? ??
          72. ????????????</props> ??
          73. ????????</property> ??
          74. ????</bean> ??
          75. </beans>??

          上面是一個完整的Spring上下文配置,可以看第一個bean “jotm”,實際上引用了Spring內部所提供的對JOTM支持的工廠類,參考下面的配置代碼段
          Java代碼
          1. <bean?id="jotm"?class="org.springframework.transaction.jta.JotmFactoryBean"/>??


          隨后,配置了JTA事務管理器,并且在管理器中使用上面所配置的jotm,如下面的代碼
          Java代碼
          1. <bean?id="txManager"?class="org.springframework.transaction.jta.JtaTransactionManager"> ??
          2. ????<property?name="userTransaction"?ref="jotm"?/> ??
          3. </bean>??


          再接下來就是配置多個數據源了,使用jotm提供的org.enhydra.jdbc.pool.StandardXAPoolDataSource類,根據類名可以明確地看出它是用以配置多個數據源的啦,配置的代碼如下
          Java代碼
          1. <bean?id="ds1"?class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"?destroy-method="shutdown"> ??
          2. ????????<property?name="dataSource"> ??
          3. ????????????<bean?class="org.enhydra.jdbc.standard.StandardXADataSource"?destroy-method="shutdown"> ??
          4. ????????????????<property?name="transactionManager"?ref="jotm"?/> ??
          5. ????????????????<property?name="driverName"?value="com.mysql.jdbc.Driver"?/> ??
          6. ????????????????<property?name="url"?value="jdbc:MySQL://localhost:3306/test"?/> ??
          7. ????????????</bean> ??
          8. ????????</property> ??
          9. ????????<property?name="user"?value="root"?/> ??
          10. ????????<property?name="password"?value="admin"?/> ??
          11. ????</bean> ??
          12. ???? ??
          13. ????<bean?id="ds2"?class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"?destroy-method="shutdown"> ??
          14. ????????<property?name="dataSource"> ??
          15. ????????????<bean?class="org.enhydra.jdbc.standard.StandardXADataSource"?destroy-method="shutdown"> ??
          16. ????????????????<property?name="transactionManager"?ref="jotm"?/> ??
          17. ????????????????<property?name="driverName"?value="com.mysql.jdbc.Driver"?/> ??
          18. ????????????????<property?name="url"?value="jdbc:MySQL://localhost:3306/test2"?/> ??
          19. ????????????</bean> ??
          20. ????????</property> ??
          21. ????????<property?name="user"?value="root"?/> ??
          22. ????????<property?name="password"?value="admin"?/> ??
          23. ????</bean>??

          這里配置的兩個數據源都連接到本地的mysql,實際上可以連接到不同的db server和不同類型的數據庫,已經經過測試,這里為了方便,在本地建立了兩個不同的數據庫(test,test2)做測試。

          隨后的配置基本上和普通的Spring上下文配置相同了,根據不同的數據源配置兩個jdbcTemplate,兩個dao分別引用不同的jdbcTemplate, 將兩個dao注入到UserService中, 最后將service納入事務管理,并在事務代理配置中配置回滾規則,意思為如遇異常,則強制回滾內容。配置如下所示
          Java代碼
          1. <property?name="transactionAttributes">???????? ??
          2. ????<props> ??
          3. ????????<prop?key="insert*">PROPAGATION_REQUIRED,-Exception</prop>???????????? ??
          4. ????</props> ??
          5. </property>??


          這樣,一個使用JOTM JTA事務的簡單應用算大致成型了,最后,寫一個JUnit,來測試一下結果
          TestXa.java
          Java代碼
          1. package?com.xa; ??
          2. ??
          3. import?org.springframework.context.ApplicationContext; ??
          4. import?org.springframework.test.AbstractDependencyInjectionSpringContextTests; ??
          5. ??
          6. import?com.xa.service.UserService; ??
          7. ??
          8. public?class?TestXa?extends?AbstractDependencyInjectionSpringContextTests ??
          9. { ??
          10. ????protected?String[]?getConfigLocations()?{ ??
          11. ????????return?new?String[]?{?"classpath:ApplicationContext-jotm.xml"?}; ??
          12. ????} ??
          13. ??
          14. ????public?void?testInsertBothDatabase()?{ ??
          15. ????????ApplicationContext?ctx?=?this.getApplicationContext(); ??
          16. ????????UserService?ut?=?(UserService)ctx.getBean("userTest"); ??
          17. ????????try?{ ??
          18. ????????????ut.insertBothDatabase("1",?null); ??
          19. ????????} ??
          20. ????????catch?(Exception?e)?{ ??
          21. ????????????e.printStackTrace(); ??
          22. ????????} ??
          23. ????} ??
          24. }??

          在test中,調用了UserService的insertBothDatabase方法,有兩個參數,userId和UserName,另外在方法的實現中調用了兩個使用不同數據源dao,分別向兩個不同的數據庫插入輸入,而test2數據庫的xa_test表中,name字段是不允許為空的,因此,在插入test2數據庫時會失敗.

          運行這個test,然后察看數據庫結果:),test和test2數據庫中都沒有插入成功,看serviceImpl中的代碼可以知道,邏輯上dao1會先于dao2執行,但是由于JTA事務,在dao2插入數據出現異常時整個事務被回滾,由于事務被配置在service層,dao1和dao2都被納入一個事務進行管理,呵呵。修改一下方法的參數,修改為
          Java代碼
          1. ut.insertBothDatabase("1",?"name1");??


          然后再試試test看數據庫結果,如何?

          posted on 2009-12-09 16:34 飛熊 閱讀(1262) 評論(0)  編輯  收藏 所屬分類: JTA


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 峨眉山市| 南郑县| 那坡县| 滨州市| 德庆县| 桃园市| 江陵县| 梓潼县| 白沙| 内丘县| 禹州市| 化隆| 达尔| 广西| 苍南县| 崇阳县| 临安市| 昌黎县| 宁晋县| 道孚县| 淅川县| 宁武县| 九寨沟县| 黔江区| 运城市| 陇南市| 武义县| 噶尔县| 铜陵市| 始兴县| 基隆市| 微山县| 千阳县| 辽阳县| 平江县| 隆子县| 博湖县| 右玉县| 伊金霍洛旗| 肃宁县| 莎车县|