`

Java中JDBC事务和JTA事务区别

 
阅读更多
一、事务概述
事务表示一个由一系列的数据库操作组成的不可分割的逻辑单位,其中的操作要么全做要么全都不做。
与事务相关的操作主要有:
BEGIN TRANSACTION; 开始一个事务,方法是:begin()
COMMIT;       提交一个事务,方法是:commit()
ROLLBACK;      回滚一个事务,方法是:rollback()
PREPARE;       准备提交一个事务,方法是:prepare()
二、事务的特性(ACID)
1、原子性:同一个事务的操作要么全部成功执行,要么全部撤消
2、隔离性:事务的所有操作不会被其它事务干扰
3、一致性:在操作过程中不会破坏数据的完整性
4、时效性 :事务的结果必须持久保存于介质上
三、事务处理方式
在JDBC连接中,使用命令声明事务的开始、提交和取消。如前一章介绍的数据库处理方式,它通过java.sql.Connection接口实现,可以启用AutoCommit。这种方式使用简单,但性能较低。
利用JavaEE规范的JTA驱动程序。这种方式性能更好,是EJB和JMS的常用方式。
Java EE 的分布式事务服务包括5个层次:事务管理器、应用服务器、资源管理器、应用程序、通信资源管理器。
事务管理器:完成事务管理
应用服务器:为应用提供服务
资源管理器:连接相应的资源
应 用程 序:需要使用事务的应用
通信资源管理器:接收事务、传播事务
四、JDBC和JTA事务区别
简单的说 jta是多库的事务 jdbc是单库的事务
1、jdbc事务
JDBC事务由Connnection对象控制管理,也就是说,事务管理实际上是在JDBC Connection中实现。事务周期限于Connection的生命周期。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。
自动提交:缺省是自动提交。一条对数据库的更新(增/删/改)代表一项事务操作,操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回滚。
手工提交:通过调用setAutoCommit(false)来禁止自动提交。这样就可把多个数据库操作的表达式作为一个事务,在操作完成后调 用commit()来进行整体提交,其中任何一个操作失败,都不会执行到commit(),并产生异常;此时可在异常捕获时调用rollback()进行回滚,以保持多次更新操作后,相关数据的一致性,示例如下:
try {
    conn =DriverManager.getConnection(...);
    conn.setAutoCommit(false);//禁止自动提交,设置回滚点
    stmt = conn.createStatement();
    stmt.executeUpdate(...); //数据库更新操作1
    stmt.executeUpdate(...); //数据库更新操作2
    conn.commit(); //事务提交
}catch(Exception ex) {
    log.error(...);
    try {
        conn.rollback(); //操作不成功则回滚
    }catch(Exception e) {
        log.error(...);
    }
}
JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。
2、jta事务
JTA(Java Transaction API)提供了跨数据库连接(或其他JTA资源)的事务管理能力。JTA事务管理则由JTA容器实现,J2ee框架中事务管理器与应用程序,资源管理器,以及应用服务器之间的事务通讯。
1)JTA的构成
a、高层应用事务界定接口,供事务客户界定事务边界的
b、X/Open XA协议(资源之间的一种标准化的接口)的标准Java映射,它可以使事务性的资源管理器参与由外部事务管理器控制的事务中
c、高层事务管理器接口,允许应用程序服务器为其管理的应用程序界定事务的边界
2)JTA的主要接口 
位于javax.transaction包中
a、UserTransaction接口:让应用程序得以控制事务的开始、挂起、提交、回滚等。由Java客户端程序或EJB调用。
b、TransactionManager 接口:用于应用服务器管理事务状态
c、Transaction接口:用于执行相关事务操作
d、XAResource接口:用于在分布式事务环境下,协调事务管理器和资源管理器的工作
e、Xid接口:为事务标识符的Java映射
注:前3个接口位于Java EE版的类库 javaee.jar 中,Java SE中没有提供!UserTransaction是编程常用的接口
注意的是JTA只提供了接口,没有具体的实现。
JTS(Java Transaction Service)是服务OTS的JTA的实现。简单的说JTS实现了JTA接口,并且符合OTS的规范。
JTA的事务周期可横跨多个JDBC Connection生命周期,对众多Connection进行调度,实现其事务性要求。
JTA可以处理任何提供符合XA接口的资源。包括:JDBC连接,数据库,JMS,商业对象等等。
3)JTA编程的基本步骤
a、首先配置JTA ,建立相应的数据源
b、建立事务:通过创建UserTransaction类的实例来开始一个事务。代码如下:
  Context ctx = new InitialContext(p) ;
   UserTransaction trans = (UserTransaction) ctx.lookup("javax. Transaction.UserTransaction")
c、开始事务:代码为 trans.begin() ;
d、找出数据源:从Weblogic Server上找到数据源,代码如下:
 DataSource ds = (DataSource) ctx.lookup(“mysqldb") ;
e、建立数据库连接:Connection mycon = ds.getConnection() ;
f、执行SQL操作:stmt.executeUpdate(sqlS);
g、完成事务:trans.commit(); / trans.rollback();
h、关闭连接:mycon.close() ;





Hibernate中以上两种事务的使用与区别:



在说他们之间的区别之前,先考虑如下几个问题:
1、getCurrentSession()与openSession()的区别?
* 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()
创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()
创建的session必须手动关闭

2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>

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

try {

conn =

DriverManager.getConnection   

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

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分布式事务总结与区别

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

    JDBC事务处理机制探秘

    1、JavaBean中使用JDBC事务处理 在JDBC中怎样将多个SQL语句组合成一个事务呢?在JDBC中,打开一个连接对象Connection时,缺省是auto-commit模式,每个SQL语句都被当作一个事务,即每次执行一个语句,都会自动的得到...

    Java Transaction API (JTA) Version 1.3 JSR-907

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

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

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

    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概述

    JTA(Java Transaction API)允许应用程序执行分布式事务处理--在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。本文的目的是要提供一个关于的Java事务处理API(JTA)...

    JAVA_API1.6文档(中文)

    javax.transaction.xa 提供定义事务管理器和资源管理器之间的协定的 API,它允许事务管理器添加或删除 JTA 事务中的资源对象(由资源管理器驱动程序提供)。 javax.xml 根据 XML 规范定义核心 XML 常量和功能。 ...

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

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

    你不知道的JDBC高级应用

    6.结果集:在JAVA中完全可以把结果集当作游标来处理,获得Statement可以添加的参数. 7.事务:设定事务的保存点,可以把事务隔离. crud c:create r:read u:update d:delete JTA 分布式事务 跨数据库的事务 JNDI TomCat ...

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

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

    Java开发热门项目

    Spring还提供了唯一的事务管理抽象,它能够在各种底层事务管理技术,例如JTA或者JDBC事务提供一个一致的编程模型。Spring提供了一个用标准Java语言编写的AOP框架,它给POJOs提供了声明式的事务管理和其他企业事务--...

    不同的事务操作代码

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

    Java事务管理学习之Hibernate详解

    hibernate是jdbc轻量级的封装,本身不具备事务管理的能力,在事物管理层面,一般是委托于底层的jdbc和jta来完成调度的。下面这篇文章主要给大家介绍了Java事务管理学习之Hibernate的相关资料,需要的朋友可以参考下...

    Java项目源码经典实用——提高必备【必学必看】

    Java远程终端工具 JTA.rar Java邮件服务器 James.rar Java邮件检验库 JEmval.zip Java验证码生成库 JCaptcha.rar JAXP数据验证引擎 Serene.zip JBoss事务处理 JBossTS.zip JDBC连接池、监控组件 Druid.zip ...

    深入理解Java事务的原理与应用

    一、什么是JAVA事务 通常的观念认为,事务仅与数据库相关。 事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性 (isolation)和持久性(durability)的缩写。事务的...

    Java 1.6 API 中文 New

    javax.transaction.xa 提供定义事务管理器和资源管理器之间的协定的 API,它允许事务管理器添加或删除 JTA 事务中的资源对象(由资源管理器驱动程序提供)。 javax.xml 根据 XML 规范定义核心 XML 常量和功能。 ...

    JavaAPI1.6中文chm文档 part1

    javax.transaction.xa 提供定义事务管理器和资源管理器之间的协定的 API,它允许事务管理器添加或删除 JTA 事务中的资源对象(由资源管理器驱动程序提供)。 javax.xml 根据 XML 规范定义核心 XML 常量和功能。 ...

    JAVA上百实例源码以及开源项目

    Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非...

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

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

    JAVA上百实例源码以及开源项目源代码

    Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非...

Global site tag (gtag.js) - Google Analytics