`
qzterminator
  • 浏览: 22881 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JTA和JDBC事务

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

    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 接口中的方法。例如:
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.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505weber/index.html



两阶段提交(Two-Phase-Commit)协议

首先,两阶段提交(Two-Phase-Commit)事务的启动与常规的单阶段提交(One-Phase-Commit)事务类似。接着,应用程序/客 户机对该两阶段提交(Two-Phase-Commit)操作中所涉及的所有数据库执行其修改工作。现在,在最终提交该事务之前,客户机通知参与的数据库准备提交(第 1 阶段)。如果客户机从数据库收到一条“okay”,就发出命令向数据库提交该事务(第 2 阶段)。最后分布式事务(Distributed Transaction)结束。





本文中的例子演示了如何在 Java 中使用 JTA 实现两阶段提交(Two-Phase-Commit)协议。在该应用程序中,如果一个事务分支报告了错误,您就要负责进行错误处理。但是“两阶段提交协议 简介”小节中提到仍然存在一个问题,那就是如果第 2 阶段中一个事务分支发生故障,该怎么办呢?

如果再次查看程序代码,您可以看到在“第 1 阶段”和“第 2 阶段”之间有一个很小的时间间隔。在这一时间间隔中,出于某种理由,其中某一参与数据库可能崩溃。如果发生了,我们将陷入分布式事务已经部分提交的情形中。

假 定下列情形:在“第 1 阶段”之后,您从 DB2 和 IDS 数据库中都收到了“okay”。在下一步中,应用程序成功提交了 DB2 的事务分支。接着,应用程序通知 DB2 事务分支提交事务。现在,在应用程序可以通知 IDS 事务分支提交它这一部分之前,IDS 引擎由于断电发生崩溃。这就是一种部分提交全局事务的情形。您现在该怎么办呢?

在重启之后,DB2 和 IDS 都将尝试恢复打开的事务分支。该引擎等待来自应用程序的提示如何做。如果应用程序没有准备重新发送“第 2 阶段”的提交,该事务分支将被引擎所启动的试探性回滚中止。这是非常糟糕的,因为这将使该全局事务处于不一致状态。

一种解决方案是用一个小型应用程序连接引擎中打开的事务分支,并通知引擎提交或回滚这一打开的事务。如果您使用 IDS 作为后端,那么还有一个隐藏的 onmode 标志,允许您结束打开的事务分支。(onmode -Z xid)。

在 DB2 UDB 中,您可以发出 LIST INDOUBT TRANSACTIONS 来获得打开的 XA 事务的有关信息。您必须查看 DB2 Information Center 中的描述来解决该问题。

上面描述的情形是一个很好的例子,也是使用应用程序服务器(Application Server)或事务监控器(Transaction Monitor)的理由。在使用一个中间层服务器时,就由该服务器负责保持事情正常。

分享到:
评论

相关推荐

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

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

    JDBC事务和JTA(XA)事务

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

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

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

    JDBC-JTA.rar_jdbc_jta_jta JDBC

    **JDBC(Java Database Connectivity)**是Java编程语言中...学习并实践这些示例,可以帮助开发者深入理解JDBC和JTA的使用,如何在Java应用中进行数据库访问和事务管理,这对于开发企业级的、高可用性的系统至关重要。

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

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

    搭建hibernate所使用的jar包,内含mysql的jdbc的jar包

    5. **事务管理**:Hibernate支持JTA和JDBC事务管理,为应用程序提供了强大的事务处理能力。 6. **缓存机制**:内置了第一级缓存(Session级别的)和第二级缓存(SessionFactory级别的),提高了数据访问速度。 **...

    JDBC事务处理机制探秘

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

    JTA事务源码示例

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

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

    本教程将深入探讨如何使用Spring框架、Java Transaction API (JTA) 和 Java Open Transaction Manager (JOTM) 来实现这样的分布式事务管理。 首先,我们来了解一下JTA。JTA是Java平台的标准事务API,它允许应用程序...

    使用JTA实现跨库事务

    本文将深入探讨如何使用JTA来实现跨库事务,确保数据的一致性和完整性。 首先,我们需要理解JTA的核心概念。JTA提供了一个统一的API,使得应用程序可以透明地处理分布式事务,而无需关心底层的事务管理细节。它定义...

    Spring+Hibernate.zip ppt

    4. **事务管理**:Hibernate 支持 JTA 和 JDBC 事务,可以方便地进行事务控制。 整合 Spring 和 Hibernate,可以实现更高效的数据访问。Spring 可以管理 Hibernate SessionFactory 和 Session,提供声明式事务管理...

    Hibernate In Action

    书中会阐述Hibernate的事务策略,包括JTA和JDBC事务,以及如何处理并发问题,如乐观锁和悲观锁的实现。 除了基本功能外,本书还将涉及更高级的主题,如性能优化、第二级缓存的使用、HQL(Hibernate查询语言)和SQL...

    SSH笔试题 j2ee笔试题

    - **事务处理**:Hibernate支持JTA和JDBC事务,提供了事务的回滚和提交。 4. **SSH整合**: - **集成优势**:SSH整合能实现MVC的分离,Spring管理Struts的Action,以及Hibernate的数据访问,增强了系统的可扩展性...

    Java开发热门项目

    对于事务管理,Spring提供了一致的编程模型,支持JTA和JDBC事务,确保了跨层事务的一致性。 Spring的面向切面编程(Aspect-Oriented Programming,AOP)模块允许开发者声明式地处理事务和其他企业服务,而无需编写...

    hibernate源代码下载

    7. 事务管理:Hibernate支持JTA和JDBC事务管理。源代码中可以学习到Hibernate如何处理事务边界,如何回滚或提交事务,以及在异常情况下如何处理事务。 8. 其他特性:如懒加载、级联操作、事件监听器等,都是...

    孙卫琴hibernate source code5

    这部分可能还会讨论事务管理的集成,如JTA和JDBC事务的配置与使用。 通过《孙卫琴精通Hibernate源码解析第五部分》的学习,开发者不仅可以深入了解Hibernate的工作原理,还能掌握如何有效地利用其特性来解决实际...

    【国信安新闻】Java框架服务.pdf

    - **事务管理**:Spring提供了声明式事务管理,可以在不侵入业务代码的情况下实现事务的控制,支持JTA和JDBC事务。 - **数据访问**:Spring提供了对JDBC的简化抽象,减少错误,同时支持与Hibernate等ORM框架的集成...

    Hibernate_3.2.0_Reference_zh_CN.rar

    8. ** Transactions**:讲解了Hibernate支持的事务处理机制,包括JTA和JDBC事务。 9. **性能优化**:给出了优化Hibernate应用的建议,如延迟加载、批处理、连接池配置等。 10. **工具**:如Hibernate Tools,提供...

    [Java学习笔记doc]Hibernate学习教程和笔记

    4. Transaction:事务处理确保了数据的一致性,Hibernate支持JTA和JDBC事务。 5. Criteria查询和HQL:Hibernate提供了面向对象的查询语言HQL(Hibernate Query Language)和Criteria API,使查询更为直观。 三、...

    hibernate实战第二版

    《Hibernate实战第二版》详细介绍了Hibernate的事务管理机制,包括JTA和JDBC事务,以及如何处理并发冲突和锁的问题。同时,书中也讨论了缓存策略,包括一级缓存和二级缓存的使用,以及第三方缓存集成如Ehcache和...

Global site tag (gtag.js) - Google Analytics