`
xuyuanshuaaa
  • 浏览: 396261 次
  • 性别: 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

    对应的`.class`文件(如`myJDBCUpdateServlet`、`myJTAServlet`、`myJDBCReadServlet`)是这些Servlet的编译后版本,它们可能包含了具体的JDBC数据库操作和JTA事务管理的代码。`www.pudn.com.txt`可能是一个文档,...

    JDBC事务和JTA(XA)事务

    JDBC事务和JTA(XA)事务 JDBC事务和JTA(XA)事务是两种常见的数据库事务类型,它们都可以用来管理数据库事务,确保数据库的一致性和可靠性。 JDBC事务 JDBC事务是Java Database Connectivity(JDBC)的事务机制,它...

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

    **JDBC事务**主要针对单个数据库连接,由数据库管理系统(DBMS)自身管理事务。JDBC提供了`Connection`对象的`commit()`和`rollback()`方法用于提交和回滚事务。这是简单的单阶段提交,适用于单一数据源的情况。 **...

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

    本文将重点探讨JDBC事务和JTA分布式事务的区别和应用场景。 首先,JDBC事务是基于数据库连接(Connection)进行管理的。在Java程序中,我们可以通过Connection对象的setAutoCommit、commit和rollback方法来控制事务...

    JTA事务源码示例

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

    springboot整合JTA组件,多数据源事务管理

    JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。下列任一个Java平台的组件都可以参与到一个JTA事务中 2、分布式事务 分布式事务(DistributedTransaction...

    在Spring中使用JTA事务管理

    本文将详细介绍如何在Spring中使用JTA事务管理,包括通过集成JOTM(Java Open Transaction Manager)以及引用Tomcat的JTA事务。 ### 1. 通过集成JOTM,直接在Spring中使用JTA事务 #### 1.1. 添加JOTM类库到类路径...

    Spring+iBatis+JOTM实现JTA事务

    通过这样的配置和测试,我们可以验证Spring+iBatis+JOTM的JTA事务管理功能是否正常工作。这种方式特别适用于需要在非J2EE容器中实现分布式事务的场景,为应用提供了强大的事务管理能力。然而,需要注意的是,JTA事务...

    spring + JTA + JOTM实现分布式事务

    对于分布式事务,Spring支持JTA事务管理,并且可以无缝集成JOTM。 1. **配置JOTM**:首先,你需要在项目的类路径下添加JOTM的依赖库。然后,在Spring的配置文件中定义JOTM的事务管理器 bean,例如: ```xml ...

    JDBC事务处理机制探秘

    总结起来,JDBC事务适用于简单的单库操作,而JTA事务则适合处理跨多个数据源的复杂事务场景。在J2EE环境中,容器管理的事务(如SessionBean中的JTA事务)能够提供更高的可伸缩性和可靠性。在实际应用中,根据需求...

    使用JTA实现跨库事务

    在提供的"SimpleDemo"示例中,可能包含了一个简单的JTA事务管理的例子,比如如何在Java代码中启动和结束一个事务,以及如何在事务中操作数据库。具体实现细节可能包括使用JPA、JDBC或其他持久化框架与JTA集成的方法...

    Spring3.1+Hibernate4.1+Atomikos3.9+MySql5.1+Tomcat5/6/7实现JTA事务管理

    Atomikos的`atomikos-tomcat-beanfactory.jar`和`atomikos-integration-extension-3.7.1-20120529.jar`是用来整合Tomcat与Atomikos的,使得Tomcat能够处理JTA事务。 6. **JTA相关库**: `transactions-api-3.9.1.jar...

    JTA 分布式事务 XAPool 1.5和1.6的所有jar包,源码包

    同时,还需要考虑与JTA事务管理器(如Atomikos、Bitronix等)的集成,以实现完整的分布式事务处理。 总结来说,XAPool是JTA分布式事务处理的重要组件,提供了一种高效的数据库连接池解决方案,对于构建大规模、高...

    Jta的jar包

    **标题与描述解析** ...总结,JTA和JBarcode分别代表了Java环境中处理分布式事务和生成条形码的两个重要工具。在开发企业级Java应用,特别是涉及数据库操作和跨系统数据交换时,理解和使用这些技术是非常关键的。

    java事务管理和事务分类

    对于JDBC和JTA事务,开发者需要显式地调用`commit()`或`rollback()`来控制事务的结束。而在容器事务中,事务的控制权交给了容器,开发者只需在业务逻辑代码中编写无事务感知的代码,容器会在适当的时候处理事务的...

    DB事务详解

    事务的实现可以通过多种方式实现,如JDBC事务、JTA事务、IBATIS事务支持等。 4.1、JDBC事务 JDBC事务是Java数据库连接(JDBC)提供的一种事务机制。JDBC事务可以通过 Connection 对象的 setAutoCommit() 方法来...

    maven springboot jta mybatis 分布式事物

    在本项目中,JTA 被用来管理跨多个数据源的事务,确保数据的一致性和完整性。Spring Boot 支持 JTA,可以通过其集成的 `Atomikos` 或 `Bitronix` 事务管理器实现分布式事务。 `MyBatis` 是一个优秀的持久层框架,它...

    jta.jar包;jta.jar包

    6. **JTA与JDBC/Java Persistence API (JPA)**: 在JDBC连接上启用JTA事务,需要使用`javax.sql.DataSource.getConnection(UserTransaction, ConnectionProperties)`方法,或者在JPA中通过`@Transactional`注解声明...

    Hibernate事务和并发控制

    事务和并发控制是数据库管理中的核心概念,特别是在使用ORM框架如Hibernate时,理解它们的工作原理至关重要。本文将深入探讨Hibernate中的事务管理和并发控制。 首先,事务是数据库操作的基本单位,它保证了数据的...

Global site tag (gtag.js) - Google Analytics