您的位置:首页 > 数据库

JTA和JDBC事务实例

2012-08-26 16:50 363 查看
TA和JDBC事务
载自:http://hi.baidu.com/quxiling/blog/item/109faecb4d00b6fc53664f45.html
2007-03-12 10:11

一般情况下,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 连接。”

要使用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
4000
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息