`

JTA

 
阅读更多

转自:http://baike.baidu.com/view/512788.htm

 

JTA概述

JTA,即Java Transaction API,译为Java事务API。
JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。

编辑本段JTA和JTS

Java事务API(JTA:Java Transaction API)和它的同胞Java事务服务(JTS:Java Transaction Service),为J2EE平台提供了分布式事务服务(distributed transaction)。
一个分布式事务(distributed transaction)包括一个事务管理器(transaction manager)和一个或多个资源管理器(resource manager)。
一个资源管理器(resource manager)是任意类型的持久化数据存储。
事务管理器(transaction manager)承担着所有事务参与单元者的相互通讯的责任。

编辑本段JTA与JDBC

JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。下列任一个Java平台的组件都可以参与到一个JTA事务中:JDBC连接、JDO PersistenceManager 对象、JMS 队列、JMS 主题、企业JavaBeans(EJB)、一个用J2EE Connector Architecture 规范编译的资源分配器。

编辑本段使用JTA的事务划分

要用JTA来划分一个事务,应用程序调用javax.transaction.UserTransaction接口中的方法。
示例4显示了一个典型的JNDI搜索的UseTransaction对象。
import javax.transaction.*;
import javax.naming.*;
// ...
InitialContext ctx = new InitialContext();
Object txObj = ctx.lookup(";java:comp/UserTransaction";);
UserTransaction utx = (UserTransaction) txObj; 
应用程序有了UserTransaction对象的引用之后,就可以象示例5那样来起动事务
utx.begin();
// ...
DataSource ds = obtainXADataSource();
Connection conn = ds.getConnection();
pstmt = conn.prepareStatement(";UPDATE MOⅥES ...";);
pstmt.setString(1, ";Spinal Tap";);
pstmt.executeUpdate();
// ...
utx.commit();
// ...
当应用程序调用commit()时,事务管理器使用两段提交协议来结束事务。
JTA事务控制的方法:
.javax.transaction.UserTransaction接口提供

编辑本段JTA和JDBC的使用

应用程序调用begin()来起动事务,即可调用commit()也可以调用rollback()来结束事务。
开发人员经常使用JDBC来作为DAO类中的底层数据操作。
如果计划使用JTA来划分事务,你将需要一个实现了javax.sql.XADataSource,javax.sql.XAConnection和javax.sql.XAResource接口JDBC的驱动。
实现了这些接口的驱动将有能力参与到JTA事务中。
一个XADataSource对象是一个XAConnection对象的工厂。XAConnections是参与到JTA事务中的连接。你需要使用应用程序服务器管理工具来建立XADataSource对象。

特殊的指令

对于特殊的指令请参考应用程序服务器文档和JDBC驱动文档。
J2EE应用程序使用JNDI来查找数据源。
一旦应用程序有了一个数据源对象的引用,这会调用javax.sql.DataSource.getConnection()来获得数据库的连接。

XA连接区别于非XA连接。

XA连接区别于非XA连接。要记住的是XA连接是一个JTA事务中的参与者。这就意味着XA连接不支持JDBC的自动提交特性。也就是说应用程序不必在XA连接上调用java.sql.Connection.commit()或java.sql.Connection.rollback()。相反,应用程序应该使用UserTransaction.begin()、UserTransaction.commit()和UserTransaction.rollback().

DAO类总结

我们已经讨论了JDBC和JTA是怎样划分事务的。每一种方法都有它的优点,因此你需要决定为你的应用程序选择一个最适应的方法。在我们团队许多最近的对于事务划分的项目中使用JDBC API来创建DAO类。
这DAO类总结如下:
⒈事务划分代码被嵌入到DAO类内部
⒉DAO类使用JDBC API来进行事务划分
⒊调用者没有划分事务的方法
⒋事务范围被限定在一个单一的JDBC连接

复杂的企业应用程序

JDBC事务对复杂的企业应用程序不总是有效的。如果你的事务将跨越多个DAO对象或多个数据库,那么下面的实现策略可能会更恰当:
⒈用JTA对事务进行划分
⒉事务划分代码被DAO分开
⒊调用者承担划分事务的责任
⒋DAO参与一个全局的事务中
JDBC方法由于它的简易性而具有吸引力,JTA方法提供了更多灵活性。你选择什么样的实现将依赖于你的应用程序的特定需求。
JTA(Java Transaction API) 为 J2EE 平台提供了分布式事务服务。
要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。例如:
utx.begin();
// ...
DataSource ds = obtainXADataSource();
Connection conn = ds.getConnection();
pstmt = conn.prepareStatement("UPDATE MOⅥES ...");
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 连本地都支持不好,更别说分布事务了。
MySql 在5.0的版本后增加了对xa的支持

编辑本段JTA方式的实现过程

用XADataSource产生的XAConnection它扩展了一个getXAResource()方法,事务通过这个方法把它加入到事务容器中进行管理.对于调用者来说,根本看不到事务是如何管理的,你只要声明开始事务,告诉容器我下面的操作要求事务参与了,最后告诉事务说到这儿可以提交或回滚了,别的都是暗箱操作。

首先,实现一个Xid类用来标识事务

在使用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();
}
因为所有这些例子中的初始化代码相同或者非常相似,仅仅是一些重要的地方的代码由不同。
例2:这个例子,与例1相似,说明了一个返回过程:
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.rollback(xid);
}
例3:这个例子说明一个分布式事务分支如何中止,让相同的连接做本地事务处理,以及它们稍后该如何继续这个分支。分布式事务的两步提交作用不影响本地事务。
xid = new MyXid(100,new byte[]{0x01},new byte[]{0x02});
xaRes.start(xid,XAResource.TMNOFLAGS);
stmt.executeUpdate("insert into test_table values (100)");
xaRes.end(xid,XAResource.TMSUSPEND);
这个更新在事务范围之外完成,所以它不受XA返回影响。
stmt.executeUpdate("insert into test_table2 values (111)");
xaRes.start(xid,XAResource.TMRESUME);
stmt.executeUpdate("insert into test_table values (200)");
xaRes.end(xid,XAResource.TMSUCCESS);
ret = xaRes.prepare(xid);
if (ret == XAResource.XA_OK) {
xaRes.rollback(xid);
}
例4:这个例子说明一个XA资源如何分担不同的事务。创建了两个事务分支,但是它们不属于相同的分布式事务。JTA允许XA资源在第一个分支上做一个两步提交,虽然这个资源仍然与第二个分支相关联。
xid1 = new MyXid(100,new byte[]{0x01},new byte[]{0x02});
xid2 = new MyXid(100,new byte[]{0x11},new byte[]{0x22});
xaRes.start(xid1,XAResource.TMNOFLAGS);
stmt.executeUpdate("insert into test_table1 values (100)");
xaRes.end(xid1,XAResource.TMSUCCESS);
xaRes.start(xid2,XAResource.TMNOFLAGS);
ret = xaRes.prepare(xid1);
if (ret == XAResource.XA_OK) {
xaRes.commit(xid2,false);
}
stmt.executeUpdate("insert into test_table2 values (200)");
xaRes.end(xid2,XAResource.TMSUCCESS);
ret = xaRes.prepare(xid2);
if (ret == XAResource.XA_OK) {
xaRes.rollback(xid2);
}
例5:这个例子说明不同的连接上的事务分支如何连接成为一个单独的分支,如果它们连接到相同的资源管理程序。这个特点改善了分布式事务的效率,因为它减少了两步提交处理的数目。两个连接到数据库服务器上的XA将被创建。每个连接创建它自己的XA资源,正规的JDBC连接和语句。在第二个XA资源开始一个事务分支之前,它将察看是否使用和第一个XA资源使用的是同一个资源管理程序。如果这是实例,它将加入在第一个XA连接上创建的第一个分支,而不是创建一个新的分支。稍后,这个事务分支使用XA资源来准备和提交。
xaDS = getDataSource();
xaCon1 = xaDS.getXAConnection("jdbc_user","jdbc_password");
xaRes1 = xaCon1.getXAResource();
con1 = xaCon1.getConnection();
stmt1 = con1.createStatement();
xid1 = new MyXid(100,new byte[]{0x01},new byte[]{0x02});
xaRes1.start(xid1,XAResource.TMNOFLAGS);
stmt1.executeUpdate("insert into test_table1 values (100)");
xaRes1.end(xid,XAResource.TMSUCCESS);
xaCon2 = xaDS.getXAConnection("jdbc_user","jdbc_password");
xaRes2 = xaCon1.getXAResource();
con2 = xaCon1.getConnection();
stmt2 = con1.createStatement();
if (xaRes2.isSameRM(xaRes1)) {
xaRes2.start(xid1,XAResource.TMJOIN);
stmt2.executeUpdate("insert into test_table2 values (100)");
xaRes2.end(xid1,XAResource.TMSUCCESS);
}
else {
xid2 = new MyXid(100,new byte[]{0x01},new byte[]{0x03});
xaRes2.start(xid2,XAResource.TMNOFLAGS);
stmt2.executeUpdate("insert into test_table2 values (100)");
xaRes2.end(xid2,XAResource.TMSUCCESS);
ret = xaRes2.prepare(xid2);
if (ret == XAResource.XA_OK) {
xaRes2.commit(xid2,false);
}
}
ret = xaRes1.prepare(xid1);
if (ret == XAResource.XA_OK) {
xaRes1.commit(xid1,false);
}
例6:这个例子说明在错误恢复的阶段,如何恢复准备好的或者快要完成的事务分支。它首先试图返回每个分支;如果它失败了,它尝试着让资源管理程序丢掉关于事务的消息。
MyXid[] xids;
xids = xaRes.recover(XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN);
for (int i=0; xids!=null && i  try {
xaRes.rollback(xids[i]);
}
catch (XAException ex) {
try {
xaRes.forget(xids[i]);
}
catch (XAException ex1) {
System.out.println("rollback/forget failed: " + ex1.errorCode);
}
}
}
分享到:
评论

相关推荐

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

    、JTA组件简介 1、JTA基本概念 JTA即Java-Transaction-API,JTA允许应用程序执行分布式事务处理,即在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序对JTA的支持极大地增强了数据访问能力。 XA协议是...

    最新的JTA规范.pdf

    ### 最新的JTA规范:Java事务API概览与解析 #### 核心概念与功能 **JTA(Java Transaction API)规范**是Java平台中处理分布式事务管理的关键组件,它定义了事务管理器与分布式系统中各个参与方之间的高级接口。...

    jta.jar包;jta.jar包

    Java Transaction API(JTA)是Java平台上的标准接口,用于管理分布式事务处理。jta.jar文件是这个API的实现库,它包含了一系列类和接口,允许应用程序在不同的数据存储系统间进行协调一致的事务操作。在Java应用中...

    jta使用手册,jta帮助文档jta使用手册,jta帮助文档

    ### Java Transaction API (JTA) 使用手册与帮助文档解析 #### 概述 Java Transaction API(JTA)是Java平台中用于处理分布式事务的核心技术之一。JTA规范定义了事务管理器与分布式事务系统中各方参与者(应用、...

    Jta的jar包

    描述中提到了"jbarcode-0.2.8"和"jbarcodebean-1.2.0",这是关于Java条形码生成库JBarcode的不同版本,但主要关注点是JTA,因为"jta-1.0.1B"和"jta-1.1"再次被提及。这表明讨论的是用于处理分布式事务的Java技术。 ...

    geronimo-jta_1.1_spec-1.1.1.jar

    《深入理解geronimo-jta_1.1_spec-1.1.1.jar在Hibernate中的应用》 在Java开发领域,尤其是涉及到企业级应用时,规范的遵循与实现至关重要。`geronimo-jta_1.1_spec-1.1.1.jar`是Apache Geronimo项目提供的一份关于...

    Springboot 动态多数据源 jta分布式事务

    本资源针对的是Spring Boot动态多数据源和JTA(Java Transaction API)分布式事务的实现,对于初学者来说非常实用。下面我们将深入探讨这些知识点。 首先,让我们了解一下Spring Boot的多数据源。在许多业务场景下...

    springboot+jta+atomikos

    本项目“springboot+jta+atomikos”旨在利用Spring Boot框架、Java Transaction API (JTA) 和 Atomikos 这一开源事务管理器来实现分布式事务的统一管理。下面将详细阐述这三个关键组件以及它们如何协同工作。 **...

    quartz_jta_collections

    在标题"quartz_jta_collections"中,我们看到与Quartz相关的三个关键组件:quartz-all-1.6.0.jar、jta-1.1.jar和commons-collections.jar。这些组件对于理解Quartz如何在分布式环境中运行以及它如何处理数据集合至关...

    最新的 jta包 用于quartz缺少jar

    在Java世界中,JTA(Java Transaction API)是用于管理分布式事务的标准接口,它允许应用程序在不同的数据存储系统之间协调事务。Quartz是一款强大的、开源的作业调度框架,广泛应用于Java应用中,用于安排和执行...

    geronimo-jta_1.1_spec-1.1.1.jar的源码

    《深入理解geronimo-jta_1.1_spec-1.1.1.jar:源码解析与在Hibernate框架中的应用》 在Java开发领域,尤其是企业级应用开发中,JTA(Java Transaction API)扮演着至关重要的角色。Geronimo-JTA_1.1_spec-1.1.1.jar...

    JTA1.1规范(sun)

    Java Transaction API(JTA)1.1规范是Java平台企业版(Java EE)中的核心组件之一,用于处理分布式事务处理。这个规范定义了接口和类,使得Java应用程序能够在不同的事务资源之间协调一致的操作,比如数据库、消息...

    分布式事务操作之Spring+JTA+mybatis源码

    本话题主要聚焦于如何在Spring框架中结合Java Transaction API (JTA) 和 MyBatis 实现分布式事务管理。下面我们将详细探讨相关知识点。 1. **分布式事务**:在分布式系统中,事务处理跨越多个资源或服务,例如...

    EJB中的JTA与JTS例子代码

    EJB中的JTA与JTS例子代码,JTA是一种高层的,与实现无关的,与协议无关的J2ee API,应用程序和应用服务器可以使用JTA来访问事务。JTS则规定了支持JTA的事务管理器的实现规范,在高层API之下实现了OMG Object ...

    atomikos_3.7_jta项目整合jar包

    这个项目整合的jar包是针对Java Transaction API (JTA) 的扩展,提供了分布式事务管理功能,使得应用程序能够在多个数据库之间进行跨库事务操作。 JTA 是Java平台标准版(Java EE)的一部分,它定义了一个接口,...

    jta1.1-doc

    《JTA 1.1 技术文档详解》 JTA(Java Transaction API)是Java平台企业版(Java EE)中的一个关键组件,用于管理分布式事务处理。JTA 1.1是其一个重要版本,提供了对跨多个数据源的事务协调能力。本文档将深入探讨...

    JTA事务源码示例

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

    Spring配置JTA事务管理

    Spring框架在企业级Java应用中广泛用于实现事务管理,而JTA(Java Transaction API)是Java平台上的标准事务处理API,适用于分布式环境。本篇文章将深入探讨如何在Spring中配置JTA事务管理,以实现跨数据库和资源的...

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

    本文将详细讲解如何利用Spring Boot、Atomikos、JPA(Java Persistence API)以及MySQL来实现JTA(Java Transaction API)分布式事务。 首先,Spring Boot是一个轻量级的框架,它简化了基于Spring的应用程序开发...

    jta.jar jbpm \hibernate

    标题中的"jta.jar jbpm \hibernate"提到了三个关键组件,它们分别是JTA(Java Transaction API)、jbpm(Business Process Management System)和Hibernate(一个流行的对象关系映射框架)。下面将对这三个概念进行...

Global site tag (gtag.js) - Google Analytics