`
xuyuanshuaaa
  • 浏览: 388291 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

JTA事务和JDBC事务

 
阅读更多
一般情况下,J2EE应用服务器支持JDBC事务、JTA事务、容器管理事务。这里讨论JTA和JDBC事务的区别。这2个是常用的DAO模式事务界定方式。
JDBC 事务
JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。
★ 在jdbc中,事务操作缺省是自动提交。也就是说,一条对数据库的更新表达式代表一项事务操作,操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回滚。
★ 在jdbc中,可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调用commit()来进行整体提交,倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时调用 rollback()进行回滚。这样做可以保持多次更新操作后,相关数据的一致性,示例如下:

Java代码

 
 1.   try {  
   2.   
   3. conn =   
   4.   
   5. DriverManager.getConnection      
   6.   
   7. ("jdbc:oracle:thin:@host:1521:SID","username","userpwd";  
   8.   
   9.        conn.setAutoCommit(false);//禁止自动提交,设置回滚点  
  10.   
  11.        stmt = conn.createStatement();  
  12.   
  13. stmt.executeUpdate(“alter table …”); //数据库更新操作1  
  14.   
  15. stmt.executeUpdate(“insert into table …”); //数据库更新操作2  
  16.   
  17.        conn.commit(); //事务提交  
  18.   
  19.      }catch(Exception ex) {      
  20.   
  21.          ex.printStackTrace();  
  22.   
  23.          try {  
  24.   
  25.           conn.rollback(); //操作不成功则回滚  
  26.   
  27.           }catch(Exception e) {  
  28.   
  29. e.printStackTrace();  
  30.   
  31.            }  
  32.   
  33. }  

  try {

conn = 

DriverManager.getConnection    

("jdbc:oracle:thin:@host:1521:SID","username","userpwd";

       conn.setAutoCommit(false);//禁止自动提交,设置回滚点

       stmt = conn.createStatement();

stmt.executeUpdate(“alter table …”); //数据库更新操作1

stmt.executeUpdate(“insert into table …”); //数据库更新操作2

       conn.commit(); //事务提交

     }catch(Exception ex) {    

         ex.printStackTrace();

         try {

          conn.rollback(); //操作不成功则回滚

          }catch(Exception e) {

e.printStackTrace();

           }

}


JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。

JTA事务

JTA(Java Transaction API) 为 J2EE 平台提供了分布式事务服务。
要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。JTA事务需要application server提供支持,创建transactionManager对象,进行分布式事务。但是tomcat不提供transactionManager服务,jboss和weblogic提供支持。tomcat可以结合spring提供支持

例如: utx.begin();
   
Java代码

  
1. // ...  
   2.      DataSource ds = obtainXADataSource();  
   3.      Connection conn = ds.getConnection();  
   4.      pstmt = conn.prepareStatement("UPDATE MOVIES ...");  
   5.      pstmt.setString(1, "Spinal Tap");  
   6.      pstmt.executeUpdate();  
   7.      // ...  
   8.      utx.commit();  

 // ...
      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的实现:
Java代码

 
 1. import javax.transaction.xa.*;   
   2. public class MyXid implements Xid   
   3. {   
   4.  protected int formatId;   
   5.  protected byte gtrid[];   
   6.  protected byte bqual[];   
   7.  public MyXid()   
   8.   {   
   9.  }   
  10.  public MyXid(int formatId, byte gtrid[], byte bqual[])   
  11.   {   
  12.   this.formatId = formatId;   
  13.   this.gtrid = gtrid;   
  14.   this.bqual = bqual;   
  15.   }   
  16.   
  17.  public int getFormatId()   
  18.   {   
  19.   return formatId;   
  20.   }   
  21.   
  22.  public byte[] getBranchQualifier()   
  23.   {   
  24.   return bqual;   
  25.   }   
  26.   
  27.  public byte[] getGlobalTransactionId()   
  28.   {   
  29.   return gtrid;   
  30.   }   
  31.   
  32. }  

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; 
 } 

}



其次,你需要创建一个你要使用的数据库的数据源:

Java代码  收藏代码

   1. public DataSource getDataSource()   
   2.  throws SQLException   
   3.   {   
   4.   SQLServerDataSource xaDS = new   
   5.    com.merant.datadirect.jdbcx.sqlserver.SQLServerDataSource();   
   6.   xaDS.setDataSourceName("SQLServer");   
   7.   xaDS.setServerName("server");   
   8.   xaDS.setPortNumber(1433);   
   9.   xaDS.setSelectMethod("cursor");   
  10.   return xaDS;   
  11. }   

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?这个例子是用“两步提交协议”来提交一个事务分支:

Java代码 

  1. XADataSource xaDS;   
   2. XAConnection xaCon;   
   3. XAResource xaRes;   
   4. Xid xid;   
   5. Connection con;   
   6. Statement stmt;   
   7. int ret;   
   8. xaDS = getDataSource();   
   9. xaCon = xaDS.getXAConnection("jdbc_user", "jdbc_password");   
  10. xaRes = xaCon.getXAResource();   
  11. con = xaCon.getConnection();   
  12. stmt = con.createStatement();   
  13. xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});   
  14. try {   
  15.    xaRes.start(xid, XAResource.TMNOFLAGS);   
  16.    stmt.executeUpdate("insert into test_table values (100)");   
  17.   xaRes.end(xid, XAResource.TMSUCCESS);   
  18.    ret = xaRes.prepare(xid);   
  19.   if (ret == XAResource.XA_OK) {   
  20.     xaRes.commit(xid, false);   
  21.    }   
  22. }   
  23. catch (XAException e) {   
  24.   e.printStackTrace();   
  25. }   
  26. finally {   
  27.   stmt.close();   
  28.  con.close();   
  29.   xaCon.close();   
  30. }  

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例子:

Java代码  收藏代码

   1. <?xml version="1.0" encoding="UTF-8"?> 
   2.  
   3. <!-- ===================================================================== --> 
   4. <!--    --> 
   5. <!--  JBoss Server Configuration    --> 
   6. <!-- Thanks to Horia Muntean <horia@bvb.ro>   --> 
   7. <!-- ===================================================================== --> 
   8.  
   9. <!-- $Id: db2-xa-ds.xml,v 1.1.2.1 2003/05/30 18:25:57 d_jencks Exp $ --> 
  10.  
  11.  
  12. <datasources> 
  13.    <!-- 
  14.        XADatasource for DB2 V8.1 (app driver) 
  15.        copy $db2_install_dir/java/db2java.zip into $jboss_install_dir/server/default/lib 
  16.    --> 
  17.  
  18.    <xa-datasource> 
  19.      <jndi-name>DB2XADS</jndi-name> 
  20.      <xa-datasource-class>COM.ibm.db2.jdbc.DB2XADataSource</xa-datasource-class> 
  21.      <xa-datasource-property name="DatabaseName">yout_database_name</xa-datasource-property> 
  22.      <xa-datasource-property name="User">your_user</xa-datasource-property> 
  23.      <xa-datasource-property name="Password">your_password</xa-datasource-property> 
  24.    </xa-datasource> 
  25. </datasources> 

<?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.htmlhttp://www-128.ibm.com/developerworks/cn/java/j-dao/
http://www.vermicelli.pasta.cs.uit.no/ipv6/students/andrer/doc/html/node18.html
分享到:
评论

相关推荐

    JDBC-JTA.rar_jdbc_jta_jta JDBC

    JDBC和JTA访问数据库和管理事务的方法实例:JDBC访问数据库的一般方法、及JTA事务管理的方法介绍。

    JDBC事务 JTA事务 传播特性 隔离级别

    有关JDBC事务 JTA事务 传播特性 隔离级别等等

    JTA事务源码示例

    Spring+iBatis+JOTM实现JTA事务: 如何处理跨库事物:spring + jtom 的jta事务是个很好的选择. 这个源码示例非常不错,包括所有的源码和jar包,下载后eclipse 或 myeclipse 导入就能用。 里面有详细的说明和注释,...

    JDBC事务和JTA(XA)事务

    JDBC事务和JTA(XA)事务

    Java中JDBC事务与JTA分布式事务总结与区别

    Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务,本文详细介绍了JDBC事务与JTA分布式事务,有需要的可以了解一下。

    JDBC事务处理机制探秘

    1、JavaBean中使用JDBC事务处理 在JDBC中怎样将多个SQL语句组合成一个事务呢?在JDBC中,打开一个连接对象Connection时,缺省是auto-commit模式,每个...2、SessionBean中的JTA事务 。 。 。 。 。 。 。 。 。

    不同的事务操作代码

    不同的事务操作代码,包括 JTA全局事务 JDBC局部事务 以及包含了Hibernate事务

    Java Transaction API (JTA) Version 1.3 JSR-907

    Java JTA 与 JDBC 类似,也是 Java 中的一种规范,JDBC 定义了 Java 应用程序如何访问数据库,而 JTA 则定义 Java 应用程序如何实现分布式事务。 Java 中与数据库相关的技术还包括 JPA,它们都分别提供了一套事务 ...

    06丨20%的业务代码的Spring声明式事务,可能都没处理正确

    Spring 针对 Java Transaction API (JTA)、JDBC、Hibernate 和 Java Persistence API (JPA) 等事务 API,实现了一致的编程模型,而 Spring 的声明式事务功能更是提供了极其方便的事务配置方式,配合 Spring Boot 的...

    分布式事务实践 解决数据一致性

    介绍了Spring的事务机制、事物抽象、内部事务和外部事物,以及常用的几种事务管理的实现,包括DataSource、JPA、JMS、JTA都通过实例进行说明。还有XA以及两阶段提交,并通过实例演示了使用JTA,通过两阶段提交,实现...

    Java中各种事务管理技术的总结

    内容包括事务及其控制的基本概念,Oracle中的事务处理,以及JDBC,EJB,JTA事务管理内容的总结,最后还介绍了事务管理的技巧,是了解和学习JAVA事务处理不可多得的第一手资料!

    你不知道的JDBC高级应用

    1.批处理:对数据库的CRUD速度会有质的飞跃.经常在对批量CUD的时候进行. 2.数据库连接池:把对数据库的连接放入一个容器中,...JTA 分布式事务 跨数据库的事务 JNDI TomCat 方便分布式处理 dbcp JDBC连接池 ............

    spring cloud事务从入门到精通

    4mysq|-JDBC事务讲解1 5mysqI-JDBC事务讲解2 6搭建一个spring-boot项目 7idea插件easycode 8spring-boot标签事务 9spring-boot jms介绍 10spring-boot jta单数据源事务实例 11spring-boot jta多数据源事务实例

    Java_JDBC由浅入深

    8.5 JTA事务的介绍 56 8.6 数据库的隔离级别介绍 56 8.6.1 未提交读 57 8.6.2 提交读 58 8.6.3 重复读 59 8.6.4 序列化读 60 8.7 小结 62 第九节 PreparedStatement接口的使用 62 第十节 CallableStatement接口的...

    Java Transaction API概述

    JDBC驱动程序的JTA支持极大地增强了数据访问能力。本文的目的是要提供一个关于的Java事务处理API(JTA)的高级的概述,以及与分布式事务相关的内容。一个事务处理定义了一个工作逻辑单元,要么彻底成功要么不产生...

    spring+jotm 多数据源事务管理(一)jdbc

    JOTM (Java Open Transaction Manager)是由ObjectWeb协会开发的功能完整的且资源开放的独立的...它提供了 JAVA 应用程序的事务支持,而且与 JTA( JAVA 事务 API)兼容。您可以在JOTM home page 了解到更多的详细信息。

    oracle-transaction.rar_oracle

    oracle数据库事务的概念和相关概念,以及事务级别的划分。分别介绍了jdbc事务和jta事务。

    JAVA设计模式之事务处理.pdf

    事务处理是企业应用需要解决的最主要的问题之一。J2EE通过JTA提供了完整的事务管理能力,包括多个事务性资 源的管理能力。但是大部分应用都是运行在单一的事务性资源之上...本地事务服务已然足够(比如JDBC事务管理)。

    Spring3配置声明式事务

    在Spring3中配置声明式事务比早期版本显得更加简便。只需要几行配置文件+注解就可以实现面向切面的AOP事务

    在SPRING中实现事务暂停

    后台的事务管理器支持简单的基于JDBC的事务和全功能的基于JTA的J2EE事务。这篇文章详细的讨论了Spring的事务管理特性。重点是如何在使用JTA作为后台事务策略的基础上让POJO利用Spring的声明性事务,这也显示了Spring...

Global site tag (gtag.js) - Google Analytics