<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Vincent.Chan‘s Blog

    常用鏈接

    統(tǒng)計

    積分與排名

    網(wǎng)站

    最新評論

    JTA知識

    JTA知識

             JTA主要用于分布式的多個數(shù)據(jù)源的兩階段提交的事務(wù),JDBCConnection提供的單個數(shù)據(jù)源的事務(wù); 后者因為只涉及到一個數(shù)據(jù)源,所以其事務(wù)可以由數(shù)據(jù)庫自己單獨實現(xiàn), JTA事務(wù)因為其分布式和多數(shù)據(jù)源的特性, 不可能由任何"一個"數(shù)據(jù)源實現(xiàn)事務(wù), 因此JTA中的事務(wù)是由"事務(wù)管理器"實現(xiàn)的,它會在多個數(shù)據(jù)源之間統(tǒng)籌事務(wù),具體使用的技術(shù)就是所謂的"兩階段提交", 一般JTA事務(wù)都是用于EJB(因為EJB本身也是分布式的), 所以一般的應(yīng)用服務(wù)器都有自己的事務(wù)管理器用來管理JTA事務(wù),注意這并不表示EJB容器有管理事務(wù)的功能; 事實上也有單獨的事務(wù)管理器比如開源的Tyrex. 如果只用Tomcat做應(yīng)用服務(wù)器的話是不能使用JTA事務(wù)的;

    使用 JDBC 事務(wù)界定時,您可以將多個 SQL 語句結(jié)合到一個事務(wù)中。JDBC 事務(wù)的一個缺點是事務(wù)的范圍局限于一個數(shù)據(jù)庫連接。一個 JDBC 事務(wù)不能跨越多個數(shù)據(jù)庫。在下面,我們將看一下如何用 JTA 進(jìn)行事務(wù)界定。因為 JTA 不像 JDBC 那樣有名,所以我們首先做一個簡介。

    JTA 簡介
    Java
    事務(wù) API(JTA) 及其同門兄弟 Java 事務(wù)服務(wù)(Java Transaction Service JTS) J2EE 平臺提供了分布式事務(wù)服務(wù)。一個分布式的事務(wù)涉及一個事務(wù)管理器和一個或者多個資源管理器。一個資源管理器是任何類型的持久性的數(shù)據(jù)存儲。事務(wù)管理器負(fù)責(zé)協(xié)調(diào)所有事務(wù)參與者之間的通信。事務(wù)管理器與資源管理器之間的關(guān)系如圖 2 所示:

    2. 一個事務(wù)管理器和資源管理器

    JTA 事務(wù)比 JDBC 事務(wù)功能更強(qiáng)。JDBC 事務(wù)局限為一個數(shù)據(jù)庫連接,而 JTA 事務(wù)可以有多個參與者。所有下列 Java 平臺組件都可以參與 JTA 事務(wù):

    JDBC 連接

    JDO PersistenceManager 對象

    JMS 隊列

    JMS 主題

    企業(yè) JavaBeans

    符合 J2EE 連接體系結(jié)構(gòu)(J2EE Connector Architecture)規(guī)范的資源適配器

    使用 JTA 的事務(wù)界定
    要用 JTA 進(jìn)行事務(wù)界定,應(yīng)用程序要調(diào)用 javax.transaction.UserTransaction 接口中的方法。清單 4 顯示了對 UserTransaction 對象的典型 JNDI 查詢:

    清單 4. 一個對 UserTransaction 對象的 JDNI 查詢

    import javax.transaction.*; import javax.naming.*; // ... InitialContext ctx = new InitialContext(); Object txObj = ctx.lookup("java:comp/UserTransaction"); UserTransaction utx = (UserTransaction) txObj;

    當(dāng)應(yīng)用程序找到了 UserTransaction 對象后,就可以開始事務(wù)了,如清單 5 所示:

    清單 5. JTA 開始一個事務(wù)

    utx.begin(); // ... DataSource ds = obtainXADataSource(); Connection conn = ds.getConnection(); pstmt = conn.prepareStatement("UPDATE MOVIES ..."); pstmt.setString(1, "Spinal Tap"); pstmt.executeUpdate(); // ... utx.commit(); // ...

    當(dāng)應(yīng)用程序調(diào)用 commit()時,事務(wù)管理器用一個兩階段的提交協(xié)議結(jié)束事務(wù)。

    控制事務(wù)的 JTA 方法
    javax.transaction.UserTransaction
    接口提供了以下事務(wù)控制方法:

    public void begin()

    public void commit()

    public void rollback()

    public int getStatus()

    public void setRollbackOnly()

    public void setTransactionTimeout(int)

    應(yīng)用程序調(diào)用 begin() 開始事務(wù)。應(yīng)用程序調(diào)用 commit() 或者 rollback() 結(jié)束事務(wù)。參閱參考資料以了解更多關(guān)于用 JTA 進(jìn)行事務(wù)管理的內(nèi)容。

    使用 JTA JDBC
    開發(fā)人員通常在 DAO 類中用 JDBC 進(jìn)行底層數(shù)據(jù)操作。如果計劃用 JTA 界定事務(wù),那么就需要有一個實現(xiàn) javax.sql.XADataSourcejavax.sql.XAConnection javax.sql.XAResource 接口的 JDBC 驅(qū)動程序。一個實現(xiàn)了這些接口的驅(qū)動程序?qū)⒖梢詤⑴c JTA 事務(wù)。一個 XADataSource 對象就是一個 XAConnection 對象的工廠。XAConnections 是參與 JTA 事務(wù)的 JDBC 連接。

    您將需要用應(yīng)用服務(wù)器的管理工具設(shè)置 XADataSource。從應(yīng)用服務(wù)器和 JDBC 驅(qū)動程序的文檔中可以了解到相關(guān)的指導(dǎo)。

    J2EE 應(yīng)用程序用 JNDI 查詢數(shù)據(jù)源。一旦應(yīng)用程序找到了數(shù)據(jù)源對象,它就調(diào)用 javax.sql.DataSource.getConnection() 以獲得到數(shù)據(jù)庫的連接。

    XA 連接與非 XA 連接不同。一定要記住 XA 連接參與了 JTA 事務(wù)。這意味著 XA 連接不支持 JDBC 的自動提交功能。同時,應(yīng)用程序一定不要對 XA 連接調(diào)用 java.sql.Connection.commit() 或者 java.sql.Connection.rollback()。相反,應(yīng)用程序應(yīng)該使用 UserTransaction.begin()UserTransaction.commit() serTransaction.rollback()

    選擇最好的方式
    我們討論了如何用 JDBC JTA 界定事務(wù)。每一種方式都有其優(yōu)點,您需要決定哪一種最適合于您的應(yīng)用程序。

    在最近的許多項目中,我們小組是用 JDBC API 進(jìn)事務(wù)界定來構(gòu)建 DAO 類的。這些 DAO 類可以總結(jié)如下:

    事務(wù)界定代碼嵌入在 DAO 類中。

    DAO 類使用 JDBC API 進(jìn)行事務(wù)界定。

    調(diào)用者不能界定事務(wù)。

    事務(wù)范圍局限于單個 JDBC 連接。

    JDBC 事務(wù)并不總是適合復(fù)雜的企業(yè)應(yīng)用程序。如果您的事務(wù)要跨越多個 DAO 或者多個數(shù)據(jù)庫,那么下列實現(xiàn)策略也許更合適:

    事務(wù)用 JTA 界定。

    事務(wù)界定代碼從 DAO 中分離出來。

    調(diào)用者負(fù)責(zé)界定事務(wù)。

    DAO 加入一個全局事務(wù)。

    JDBC 方式由于其簡單性而具有吸引力,JTA 方式提供了更大的靈活性。您所選擇的實現(xiàn)將取決于應(yīng)用程序的特定需求。

    日志記錄和 DAO
    一個良好實現(xiàn)的 DAO 類將使用日志記錄來捕捉有關(guān)其運行時行為的細(xì)節(jié)。您可以選擇記錄異常、配置信息、連接狀態(tài)、JDBC 驅(qū)動程序元數(shù)據(jù)、或者查詢參數(shù)。日志對于開發(fā)的所有階段都很有用。我經(jīng)常在開發(fā)時、測試時和生產(chǎn)中分析應(yīng)用程序日志。

    在本節(jié),我將展示一個顯示如何將 Jakarta Commons Logging 加入到 DAO 中的代碼示例。在這之前,讓我們回顧一下一些基本知識。

    選擇日志庫
    許多開發(fā)人員使用一種原始格式進(jìn)行日志記錄:System.out.println System.err.printlnPrintln 語句速度快且使用方便,但是它們沒有提供全功能的日志記錄系統(tǒng)所具有的功能。表 2 列出了 Java 平臺的日志庫:

    2. Java 平臺的日志庫

    日志庫

    開放源代碼?

    URL

    java.util.logging

    不是

    http://java.sun.com/j2se/

    Jakarta Log4j

    http://jakarta.apache.org/log4j/

    Jakarta Commons Logging

    http://jakarta.apache.org/commons/logging.html

    java.util.logging J2SE 1.4 平臺上的標(biāo)準(zhǔn) API。不過,大多數(shù)開發(fā)人員同意 Jakarta Log4j 提供了更多的功能和更大的靈活性。Log4j 優(yōu)于 java.util.logging 的一點是它同時支持 J2SE 1.3 J2SE 1.4 平臺。

    Jakarta Commons Logging 可以與 java.util.logging 或者 Jakarta Log4j 一同使用。Commons Logging 是一個日志抽象層,它隔離了應(yīng)用程序與底層日志實現(xiàn)。使用 Commons Logging,您可以通過改變配置文件更換底層日志實現(xiàn)。Commons Logging Jakarta Struts 1.1 Jakarta HttpClient 2.0 中使用。

    一個日志記錄示例
    清單 7 顯示了如何在 DAO 類中使用 Jakarta Commons Logging

    清單 7. DAO 類中的 Jakarta Commons Logging

    import org.apache.commons.logging.*; class DocumentDAOImpl implements DocumentDAO { static private final Log log = LogFactory.getLog(DocumentDAOImpl.class); public void deleteDocument(String id) { // ... log.debug("deleting document: " + id); // ... try { // ... data operations ... } catch (SomeException ex) { log.error("Unable to delete document", ex); // ... handle the exception ... } } }

    日志記錄是所有任務(wù)關(guān)鍵型應(yīng)用程序的重要部分。如果在 DAO 中遇到故障,那么日志通常可以提供判斷出錯位置的最好信息。將日志加入到 DAO 可以保證您有機(jī)會進(jìn)行調(diào)試和故障排除。

    DAO 中的異常處理
    我們討論過了事務(wù)界定和日志,現(xiàn)在對于如何在數(shù)據(jù)訪問對象上應(yīng)用它們有了更深入的理解。我們的第三個和最后一個討論議題是異常處理。遵從幾個簡單的異常處理指導(dǎo)可以使您的 DAO 更容易使用、更健壯及更易于維護(hù)。

    在實現(xiàn) DAO 模式時,考慮以下問題:

    DAO 的公共接口中的方法是否拋出檢查過的異常?

    如果是的話,拋出何種檢查過的異常?

    DAO 實現(xiàn)類中如何處理異常?

    在使用 DAO 模式的過程中,我們的小組開發(fā)了一些處理異常的原則。遵從這些原則可以極大地改進(jìn)您的 DAO

    DAO 方法應(yīng)該拋出有意義的異常。

    DAO 方法不應(yīng)該拋出 java.lang.Exceptionjava.lang.Exception 太一般化了。它不傳遞關(guān)于底層問題的任何信息。

    DAO 方法不應(yīng)該拋出 java.sql.SQLExceptionSQLException 是一個低級別的 JDBC 異常。一個 DAO 應(yīng)該力爭封裝 JDBC 而不是將 JDBC 公開給應(yīng)用程序的其余部分。

    只有在可以合理地預(yù)期調(diào)用者可以處理異常時,DAO 接口中的方法才應(yīng)該拋出檢查過的異常。如果調(diào)用者不能以有意義的方式處理這個異常,那么考慮拋出一個未檢查的(運行時)異常。

    如果數(shù)據(jù)訪問代碼捕獲了一個異常,不要忽略它。忽略捕獲的異常的 DAO 是很難進(jìn)行故障診斷的。

    使用鏈接的異常將低級別的異常轉(zhuǎn)化為高級別的異常。

    考慮定義標(biāo)準(zhǔn) DAO 異常類。Spring Framework (參閱參考資料)提供了很好的一套預(yù)定義的 DAO 異常類。

    有關(guān)異常和異常處理技術(shù)的更多信息參閱參考資料

    實現(xiàn)實例: MovieDAO
    MovieDAO
    是一個展示本文中討論的所有技術(shù)的 DAO:事務(wù)界定、日志和異常處理。您可以在參考資料一節(jié)中找到 MovieDAO 源代碼。代碼分為三個包:

    daoexamples.exception

    daoexamples.movie

    daoexamples.moviedemo

    DAO 模式的這個實現(xiàn)包含下面列出的類和接口:

    daoexamples.movie.MovieDAOFactory

    daoexamples.movie.MovieDAO

    daoexamples.movie.MovieDAOImpl

    daoexamples.movie.MovieDAOImplJTA

    daoexamples.movie.Movie

    daoexamples.movie.MovieImpl

    daoexamples.movie.MovieNotFoundException

    daoexamples.movie.MovieUtil

    MovieDAO 接口定義了 DAO 的數(shù)據(jù)操作。這個接口有五個方法,如下所示:

    public Movie findMovieById(String id)

    public java.util.Collection findMoviesByYear(String year)

    public void deleteMovie(String id)

    public Movie createMovie(String rating, String year, String, title)

    public void updateMovie(String id, String rating, String year, String title)

    daoexamples.movie 包包含 MovieDAO 接口的兩個實現(xiàn)。每一個實現(xiàn)使用一種不同的方式進(jìn)行事務(wù)界定,如表 3 所示:

    3. MovieDAO 實現(xiàn)

     

    MovieDAOImpl

    MovieDAOImplJTA

    實現(xiàn) MovieDAO 接口?

    通過 JNDI 獲得 DataSource

    DataSource 獲得 java.sql.Connection 對象?

    DAO 在內(nèi)部界定事務(wù)?

    使用 JDBC 事務(wù)?

    使用一個 XA DataSource

    參與 JTA 事務(wù)?

    MovieDAO 演示應(yīng)用程序
    這個演示應(yīng)用程序是一個名為 daoexamples.moviedemo.DemoServlet servlet 類。DemoServlet 使用這兩個 Movie DAO 查詢和更新表中的電影數(shù)據(jù)。

    這個 servlet 展示了如何將支持 JTA MovieDAO Java 消息服務(wù)(Java Message Service)結(jié)合到一個事務(wù)中,如清單 8 所示。

    清單 8. MovieDAO JMS 代碼結(jié)合到一個事務(wù)中

    UserTransaction utx = MovieUtil.getUserTransaction(); utx.begin(); batman = dao.createMovie("R", "2008", "Batman Reloaded"); publisher = new MessagePublisher(); publisher.publishTextMessage("I'll be back"); dao.updateMovie(topgun.getId(), "PG-13", topgun.getReleaseYear(), topgun.getTitle()); dao.deleteMovie(legallyblonde.getId()); utx.commit();

    要運行這個演示應(yīng)用程序,需要在應(yīng)用服務(wù)器上配置一個 XA 數(shù)據(jù)源和一個非 XA 數(shù)據(jù)源。然后,部署 daoexamples.ear 文件。這個應(yīng)用程序可以在任何兼容 J2EE 1.3 的應(yīng)用服務(wù)器上運行。參閱參考資料以獲得 EAR 文件和源代碼。

    結(jié)束語
    正如本文所展示的,實現(xiàn) DAO 模式需要做比編寫低級別的數(shù)據(jù)訪問代碼更多的工作。現(xiàn)在,通過選擇一個適合您的應(yīng)用程序的事務(wù)界定策略、通過在 DAO 類中加入日志記錄,以及通過遵從幾項簡單的異常處理原則,您可以構(gòu)建更好的 DAO

    參考資料

    daoexamples.sourceforge.net上下載 MovieDAO 源代碼。

    想要學(xué)習(xí)有關(guān)數(shù)據(jù)訪問對象模式的更多內(nèi)容?可以從核心 J2EE 模式主頁開始。

    Kyle Brown "A stepped approach to J2EE testing with SDAO"(developerWorks2003 3 )提供了對數(shù)據(jù)訪問對象和 DAO 設(shè)計模式的簡要介紹。

    Dragonslayer 的教程"Create persistent application data with Java Data Objects"(developerWorks2003 7 )向您展示了如何結(jié)合 Struts DAO 模式以用于影響小的企業(yè)數(shù)據(jù)持久性。

    Srikanth Shenoy "EJB 異常處理的最佳做法"(developerWorks2002 5 )介紹了異常處理基礎(chǔ)和使用 Log4J 進(jìn)行日志記錄。

    Java 理論與實踐系列從"理解 JTS -- 事務(wù)處理簡介"開始(developerWorks20023)提供了對 Java 事務(wù) API 的三部分介紹。

    Java Transaction API J2EE 平臺的關(guān)鍵部分。

    Jakarta Log4j Java 應(yīng)用程序的世界級日志庫。

    Jakarta Commons Logging 提供了容易使用的日志抽象層。

    Spring Framework JDBC 和事務(wù)管理提供了抽象層。此外,這個框架包含標(biāo)準(zhǔn)的 DAO 異常類和 JNDI 幫助器類。

    Rod Johnson J2EE Design and Development (Wrox Press2002 )是每一位 J2EE 開發(fā)人員都應(yīng)該收藏的。本書充滿了應(yīng)用程序設(shè)計策略、實用編程技巧和實際的例子。

    Josh Bloch Effective Java Programming Language Guide (Addison Wesley2001 )展示了異常處理和類庫設(shè)計的最佳實踐。

    參閱 Java 技術(shù)專區(qū)的教程頁面,從 developerWorks 獲得免費的 Java 技術(shù)教程的完整列表。

    developerWorks Java 技術(shù)專區(qū)中可以找到數(shù)百篇關(guān)于 Java 編程的各個方面的文章。

    posted on 2006-02-20 20:45 Vincent.Chen 閱讀(333) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 久久综合国产乱子伦精品免费| 成人免费网站视频www| 亚洲乱色伦图片区小说 | 亚洲色大成网站WWW久久九九| 亚洲日韩激情无码一区| 亚洲一级二级三级不卡| 国产成人亚洲精品| 羞羞网站免费观看| a级毛片免费完整视频| 最近中文字幕高清免费中文字幕mv| 日韩亚洲国产高清免费视频| 好吊妞788免费视频播放| 亚洲综合色区在线观看| 精品亚洲麻豆1区2区3区| 亚洲成av人片在www鸭子| 国产免费久久精品丫丫| 国产成人精品免费视频动漫| 免费精品一区二区三区在线观看| 亚洲日韩VA无码中文字幕| 亚洲国产老鸭窝一区二区三区| 亚洲一卡2卡三卡4卡无卡下载 | 在线91精品亚洲网站精品成人| 中文字幕免费视频精品一| 亚洲成人免费电影| 四虎精品亚洲一区二区三区| 久久久亚洲欧洲日产国码农村| 亚洲精华国产精华精华液好用| 成av免费大片黄在线观看| 91成年人免费视频| 国产亚洲一区二区三区在线不卡 | 无码高潮少妇毛多水多水免费| 亚洲伊人久久综合中文成人网| 久久久久亚洲av无码专区喷水 | 亚洲av日韩综合一区久热| 99在线免费视频| 午夜视频免费成人| 亚洲精品免费在线观看| 日本亚洲中午字幕乱码| 亚洲一级毛片免费看| 精品亚洲成α人无码成α在线观看| 亚洲一区二区三区无码国产 |