風人園

          弱水三千,只取一瓢,便能解渴;佛法無邊,奉行一法,便能得益。
          隨筆 - 99, 文章 - 181, 評論 - 56, 引用 - 0
          數據加載中……

          JTA和JDBC事務 (ZT)

          ?

          ?一般情況下,J2EE應用服務器支持JDBC事務、JTA事務、容器管理事務。這里討論JTA和JDBC事務的區別。這2個是常用的DAO模式事務界定方式。
          JDBC 事務
          ?JDBC 事務是用 Connection 對象控制的。JDBC Connection 接口( java.sql.Connection )提供了兩種事務模式:自動提交和手工提交。例如如下片斷:
          ?import java.sql.*;
          ????? import javax.sql.*;

          ????? // ...
          ????? DataSource ds = obtainDataSource();
          ????? Connection conn = ds.getConnection();
          ????? conn.setAutoCommit(false);
          ????? // ...
          ????? pstmt = conn.prepareStatement("UPDATE MOVIES ...");
          ????? pstmt.setString(1, "The Great Escape");
          ????? pstmt.executeUpdate();
          ????? // ...
          ????? conn.commit();
          ????? // ...

          ?JDBC 事務的一個缺點是事務的范圍局限于一個數據庫連接。一個 JDBC 事務不能跨越多個數據庫。
          JTA事務
          ?JTA(Java Transaction API) 為 J2EE 平臺提供了分布式事務服務。
          ?要用 JTA 進行事務界定,應用程序要調用 javax.transaction.UserTransaction 接口中的方法。例如:
          ?utx.begin();
          ????? // ...
          ????? DataSource ds = obtainXADataSource();
          ????? Connection conn = ds.getConnection();
          ????? pstmt = conn.prepareStatement("UPDATE MOVIES ...");
          ????? pstmt.setString(1, "Spinal Tap");
          ????? pstmt.executeUpdate();
          ????? // ...
          ????? utx.commit();

          ?讓我們來關注下面的話:
          ?“用 JTA 界定事務,那么就需要有一個實現 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驅動程序。一個實現了這些接口的驅動程序將可以參與 JTA 事務。一個 XADataSource 對象就是一個 XAConnection 對象的工廠。 XAConnection s 是參與 JTA 事務的 JDBC 連接?!?br />?要使用JTA事務,必須使用XADataSource來產生數據庫連接,產生的連接為一個XA連接。
          ?XA連接(javax.sql.XAConnection)和非XA(java.sql.Connection)連接的區別在于:XA可以參與JTA的事務,而且不支持自動提交。
          ???? Note:
          Oracle, Sybase, DB2, SQL Server等大型數據庫才支持XA, 支持分布事務。
          My SQL 連本地都支持不好,更別說分布事務了。
          JTA方式的實現過程
          ?? 用XADataSource產生的XAConnection它擴展了一個getXAResource()方法,事務通過這個方法把它加入到事務容器中進行管理.對于調用者來說,根本看不到事務是如果管理的,你只要聲明開始事務,告訴容器我下面的操作要求事務參與了,最后告訴事務說到這兒可以提交或回滾了,別的都是黑箱操作。
          ?在使用JTA之前,你必須首先實現一個Xid類用來標識事務(在普通情況下這將由事務管理程序來處理)。Xid包含三個元素:formatID、gtrid(全局事務標識符)和bqual(分支修飾詞標識符)。
          ?下面的例子說明Xid的實現:

          import javax.transaction.xa.*;
          public class MyXid implements Xid
          {
           protected int formatId;
           protected byte gtrid[];
           protected byte bqual[];
           public MyXid()
           {
           }
           public MyXid(int formatId, byte gtrid[], byte bqual[])
           {
            this.formatId = formatId;
            this.gtrid = gtrid;
            this.bqual = bqual;
           }

           public int getFormatId()
           {
            return formatId;
           }

           public byte[] getBranchQualifier()
           {
            return bqual;
           }

           public byte[] getGlobalTransactionId()
           {
            return gtrid;
           }

          }
          ?其次,你需要創建一個你要使用的數據庫的數據源:

          public DataSource getDataSource()
           throws SQLException
           {
            SQLServerDataSource xaDS = new
            com.merant.datadirect.jdbcx.sqlserver.SQLServerDataSource();
            xaDS.setDataSourceName("SQLServer");
            xaDS.setServerName("server");
            xaDS.setPortNumber(1433);
            xaDS.setSelectMethod("cursor");
            return xaDS;
          }

            例1?這個例子是用“兩步提交協議”來提交一個事務分支:

          XADataSource xaDS;
          XAConnection xaCon;
          XAResource xaRes;
          Xid xid;
          Connection con;
          Statement stmt;
          int ret;
          xaDS = getDataSource();
          xaCon = xaDS.getXAConnection("jdbc_user", "jdbc_password");
          xaRes = xaCon.getXAResource();
          con = xaCon.getConnection();
          stmt = con.createStatement();
          xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
          try {
            xaRes.start(xid, XAResource.TMNOFLAGS);
            stmt.executeUpdate("insert into test_table values (100)");
            xaRes.end(xid, XAResource.TMSUCCESS);
            ret = xaRes.prepare(xid);
            if (ret == XAResource.XA_OK) {
              xaRes.commit(xid, false);
             }
          }
          catch (XAException e) {
           e.printStackTrace();
          }
          finally {
           stmt.close();
           con.close();
           xaCon.close();
          }
          ?當然,實際過程中,我們不需要寫這些代碼,這些代碼是JTA最終的實現代碼。
          關于“兩步提交協議”,可以參看下面的文章:
          http://www.jspcn.net/htmlnews/11049371131251752.html

          ?http://www.vermicelli.pasta.cs.uit.no/ipv6/students/andrer/doc/html/node18.html


          選擇最好的方式
          用 JDBC API 進事務界定來構建 DAO 類的。這些 DAO 類可以總結如下:

          事務界定代碼嵌入在 DAO 類中。
          DAO 類使用 JDBC API 進行事務界定。
          調用者不能界定事務。
          事務范圍局限于單個 JDBC 連接。
          JDBC 事務并不總是適合復雜的企業應用程序。如果您的事務要跨越多個 DAO 或者多個數據庫,那么下列實現策略也許更合適:

          事務用 JTA 界定。
          事務界定代碼從 DAO 中分離出來。
          調用者負責界定事務。
          DAO 加入一個全局事務。
          JDBC 方式由于其簡單性而具有吸引力,JTA 方式提供了更大的靈活性。您所選擇的實現將取決于應用程序的特定需求。
          XADataSource例子:
          <?xml version="1.0" encoding="UTF-8"?>

          <!-- ===================================================================== -->
          <!--??? -->
          <!--? JBoss Server Configuration??? -->
          <!-- Thanks to Horia Muntean <horia@bvb.ro>?? -->
          <!-- ===================================================================== -->

          <!-- $Id: db2-xa-ds.xml,v 1.1.2.1 2003/05/30 18:25:57 d_jencks Exp $ -->


          <datasources>
          ?? <!--
          ?????? XADatasource for DB2 V8.1 (app driver)
          ?????? copy $db2_install_dir/java/db2java.zip into $jboss_install_dir/server/default/lib
          ?? -->

          ?? <xa-datasource>
          ???? <jndi-name>DB2XADS</jndi-name>
          ???? <xa-datasource-class>COM.ibm.db2.jdbc.DB2XADataSource</xa-datasource-class>
          ???? <xa-datasource-property name="DatabaseName">yout_database_name</xa-datasource-property>
          ???? <xa-datasource-property name="User">your_user</xa-datasource-property>
          ???? <xa-datasource-property name="Password">your_password</xa-datasource-property>
          ?? </xa-datasource>
          </datasources>

          引用:
          ?http://www.jspcn.net/htmlnews/11049371131251752.html
          http://www-128.ibm.com/developerworks/cn/java/j-dao/
          http://www.vermicelli.pasta.cs.uit.no/ipv6/students/andrer/doc/html/node18.html

          posted on 2006-07-27 15:19 風人園 閱讀(349) 評論(0)  編輯  收藏 所屬分類: J2EE

          主站蜘蛛池模板: 肥西县| 洛阳市| 明星| 新安县| 阿鲁科尔沁旗| 宜昌市| 花莲县| 保靖县| 贡山| 望奎县| 南安市| 安阳县| 黄平县| 正定县| 寿阳县| 丹东市| 长岭县| 阿拉善右旗| 丰城市| 静海县| 城口县| 新乡市| 恭城| 万宁市| 江西省| 河北区| 临泽县| 永春县| 中山市| 龙泉市| 衡南县| 抚远县| 平邑县| 广河县| 承德市| 长乐市| 遂平县| 青川县| 盐津县| 沙河市| 丹东市|