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)事务的启动与常规的单阶段提交(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)的理由。在使用一个中间层服务器时,就由该服务器负责保持事情正常。

JTA提供了跨数据库连接(或其他JTA资源)的事务管理能力。这一点是与JDBC Transaction最大的差异。
JDBC事务由Connnection管理,也就是说,事务管理实际上是在JDBC Connection中实现。事务周期限于Connection的生命周期。同样,对于基于JDBC的ibatis事务管理机制而言,事务管理在SqlMapClient所依托的JDBC Connection中实现,事务周期限于SqlMapClient 的生命周期。

JTA事务管理则由 JTA容器实现,JTA容器对当前加入事务的众多Connection进行调度,实现其事务性要求。JTA的事务周期可横跨多个JDBC Connection生命周期。

JDBC事务和JTA (XA)事务区别的更多相关文章

  1. 使用Atomikos Transactions Essentials实现多数据源JTA分布式事务--转载

    原文:http://www.ite/topic/122700 9.17 update:使用NonXADataSourceBean. Mysql在5.0版本和Connecter/J5.0版本后提供了XA ...

  2. XA 事务

    4.11.3 什么是XA 事务? <数据库程序员面试笔试宝典>第4章数据库基础,本章主要介绍数据库基础部分的面试题,比较适合应届毕业生,也适合由其他岗位转数据库岗位的人员.本节为大家介绍什 ...

  3. JDBC事务和JTA事务的区别

    转自:JDBC和JTA事务的区别 一.事务概述事务表示一个由一系列的数据库操作组成的不可分割的逻辑单位,其中的操作要么全做要么全都不做.与事务相关的操作主要有:BEGIN TRANSACTION: 开 ...

  4. Java中的事务——JDBC事务和JTA事务

    Java中的事务——JDBC事务和JTA事务 转载:http://www.hollischuang.com/archives/1658 之前的事务介绍基本都是数据库层面的事务,本文来介绍一下J2EE中 ...

  5. 数据库事务(1)----- JDBC事务与JTA事务

    数据库事务(一)- JDBC事务与JTA事务 本文主要对JDBC事务与JTA事务做一个简单介绍. 1. 数据库事务概念 一个数据库事务通常包含对数据库进行读或写的一个操作序列.它的存在包含有以下两个目 ...

  6. JDBC 事务和 JTA 事务

    Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. 常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供的,容器事务大多是基于 ...

  7. JTA 分布式事务

    什么是JTA - 2009-07-25 18:31:06|  分类: 技术文章|举报|字号 订阅     什么是JTA? Java Transaction API(Java事务API) (JTA)Ja ...

  8. Springboot+Atomikos+Jpa+Mysql实现JTA分布式事务

    1 前言 之前整理了一个spring+jotm实现的分布式事务实现,但是听说spring3.X后不再支持jotm了,jotm也有好几年没更新了,所以今天整理springboot+Atomikos+jp ...

  9. 分布式事务(二)Java事务API(JTA)规范

    一.引子 既然出现了分布式场景(DTP模型), 大java也及时制定出一套规范来给各大应用服务器.数据库/mq等厂商使用,以方便管理互通--->JTA闪亮登场.JTA(Java Transact ...

随机推荐

  1. My Magic Android Tour —— 处女作

    近期考试什么的都已经结束了,闲在家也没什么事做,就想着学点什么,于是便选择了学一下Android开发.一直在使用Android手机.要是自己能为自己的手机开发一个APP就好了. 好了,也不扯些废话了, ...

  2. 使用spring的@Async异步执行方法

    应用场景: 1.某些耗时较长的而用户不需要等待该方法的处理结果 2.某些耗时较长的方法,后面的程序不需要用到这个方法的处理结果时 在spring的配置文件中加入对异步执行的支持 <beans x ...

  3. Tomcat SSL配置 Connector attribute SSLCertificateFile must be defined when using SSL with APR解决

    原文地址:http://blog.csdn.net/kissliux/article/details/17392003 Tomcat 6版本配置SSL过程有两步: 1.用JDK自带的keytool.e ...

  4. 兼顾pc和移动端的textarea字数监控的实现方法

    概述 pc端移动端中文本框监控字数的功能的一种较为简单的实现,考虑到安卓和IOS输入法输入过程中是否触发keyup的差异.利用监听compositionstart判断是否开启了输入法.从而实现体验较为 ...

  5. cxf之org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cxf' available

    原因是.... 把cxf的配置文件spring-cxf-rest.xml配置结束后,没有import到spring.xml中...所以才加载不到bean.... 另附:异常org.springfram ...

  6. HDUOJ----4502吉哥系列故事——临时工计划

    吉哥系列故事——临时工计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  7. HDUOJ---1879 继续畅通工程

    继续畅通工程 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  8. C#抽象方法

    在覆盖父类的方法时,必须显式说明是在覆盖父类方法,否则相当于没有覆盖. class Animal { public void run() { Console.WriteLine("anima ...

  9. AME_IExpense费用报表通过AME审批简单例子(案例)

    2014-05-30 Created By BaoXinjian

  10. Linux内核(8) - 设备模型(下)

    设备模型拍得再玄幻,它也只是个模型,必须得落实在具体的子系统,否则就只能抱着个最佳技术奖空遗恨.既然前面已经以USB子系统的实现分析示例了分析内核源码应该如何入手,那么这里就仍然以USB子系统为例,看 ...