jta 知识

JTA知识(转载原文地址:http://blog.csdn.net/it_man/article/details/7230215)

Java Transaction API,译为Java事务API。JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JTA主要用于分布式的多个数据源的两阶段提交的事务,而JDBC的Connection提供的单个数据源的事务; 后者因为只涉及到一个数据源,所以其事务可以由数据库自己单独实现, 而JTA事务因为其分布式和多数据源的特性, 不可能由任何"一个"数据源实现事务, 因此JTA中的事务是由"事务管理器"实现的,它会在多个数据源之间统筹事务,具体使用的技术就是所谓的"两阶段提交", 一般JTA事务都是用于EJB中(因为EJB本身也是分布式的), 所以一般的应用服务器都有自己的事务管理器用来管理JTA事务,注意这并不表示EJB容器有管理事务的功能; 事实上也有单独的事务管理器比如开源的Tyrex. 如果只用Tomcat做应用服务器的话是不能使用JTA事务的;

JTA主要用于分布式的多个数据源的两阶段提交的事务,而JDBC(Java DataBase Connectivity,java数据库连接)的Connection提供的单个数据源的事务; 后者因为只涉及到一个数据源,所以其事务可以由数据库自己单独实现, 而JTA事务因为其分布式和多数据源的特性, 不可能由任何"一个"数据源实现事务, 因此JTA中的事务是由"事务管理器"实现的,它会在多个数据源之间统筹事务,具体使用的技术就是所谓的"两阶段提交", 一般JTA事务都是用于EJB中(因为EJB本身也是分布式的), 所以一般的应用服务器都有自己的事务管理器用来管理JTA事务,注意这并不表示EJB容器有管理事务的功能; 事实上也有单独的事务管理器比如开源的Tyrex. 如果只用Tomcat做应用服务器的话是不能使用JTA事务的;

使用 JDBC 事务界定时,您可以将多个 SQL 语句结合到一个事务中。JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。在下面,我们将看一下如何用 JTA 进行事务界定。因为 JTA 不像 JDBC 那样有名,所以我们首先做一个简介。

JTA 简介
Java 事务 API(JTA) 及其同门兄弟 Java 事务服务(Java TransactionService JTS)为 J2EE 平台提供了分布式事务服务。一个分布式的事务涉及一个事务管理器和一个或者多个资源管理器。一个资源管理器是任何类型的持久性的数据存储。事务管理器负责协调所有事务参与者之间的通信。事务管理器与资源管理器之间的关系如图 2 所示:

图 2. 一个事务管理器和资源管理器

JTA 事务比 JDBC 事务功能更强。JDBC 事务局限为一个数据库连接,而 JTA 事务可以有多个参与者。所有下列 Java 平台组件都可以参与 JTA 事务:

JDBC 连接

JDOPersistenceManager 对象

JMS 队列

JMS 主题

企业 JavaBeans

符合 J2EE 连接体系结构(J2EE Connector Architecture)规范的资源适配器

使用 JTA 的事务界定
要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。清单 4 显示了对 UserTransaction 对象的典型 JNDI 查询:

清单 4. 一个对 UserTransaction 对象的 JDNI 查询

import javax.transaction.*; import  javax.naming.*; // ... InitialContext ctx = new InitialContext(); Object  txObj = ctx.lookup("java:comp/UserTransaction"); UserTransaction  utx = (UserTransaction) txObj;

当应用程序找到了 UserTransaction 对象后,就可以开始事务了,如清单 5 所示:

清单 5. 用 JTA 开始一个事务

utx.begin(); // ... DataSource ds =  obtainXADataSource(); Connection conn = ds.getConnection(); pstmt =  conn.prepareStatement("UPDATE MOVIES ..."); pstmt.setString(1,  "Spinal Tap"); pstmt.executeUpdate(); // ... utx.commit(); // ...

当应用程序调用 commit()时,事务管理器用一个两阶段的提交协议结束事务。

控制事务的 JTA 方法
javax.transaction.UserTransaction 接口提供了以下事务控制方法:

public void begin()

public void commit()

public void rollback()

public int getStatus()

public void setRollbackOnly()

public void setTransactionTimeout(int)

应用程序调用 begin() 开始事务。应用程序调用 commit() 或者 rollback() 结束事务。参阅参考资料以了解更多关于用 JTA 进行事务管理的内容。

使用 JTA 和 JDBC
开发人员通常在 DAO 类中用 JDBC 进行底层数据操作。如果计划用 JTA 界定事务,那么就需要有一个实现 javax.sql.XADataSource、javax.sql.XAConnection和 javax.sql.XAResource接口的 JDBC 驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection 对象的工厂。XAConnections 是参与 JTA 事务的 JDBC 连接。

您将需要用应用服务器的管理工具设置 XADataSource。从应用服务器和 JDBC 驱动程序的文档中可以了解到相关的指导。

J2EE 应用程序用 JNDI 查询数据源。一旦应用程序找到了数据源对象,它就调用javax.sql.DataSource.getConnection() 以获得到数据库的连接。

XA 连接与非 XA 连接不同。一定要记住 XA 连接参与了 JTA 事务。这意味着 XA 连接不支持 JDBC 的自动提交功能。同时,应用程序一定不要对 XA 连接调用 java.sql.Connection.commit() 或者 java.sql.Connection.rollback()。相反,应用程序应该使用 UserTransaction.begin()、UserTransaction.commit() 和 serTransaction.rollback()。

选择最好的方式
我们讨论了如何用 JDBC 和 JTA 界定事务。每一种方式都有其优点,您需要决定哪一种最适合于您的应用程序。

您将需要用应用服务器的管理工具设置 XADataSource。从应用服务器和 JDBC 驱动程序的文档中可以了解到相关的指导。

J2EE 应用程序用 JNDI 查询数据源。一旦应用程序找到了数据源对象,它就调用 javax.sql.DataSource.getConnection()以获得到数据库的连接。

XA 连接与非 XA 连接不同。一定要记住 XA 连接参与了 JTA 事务。这意味着 XA 连接不支持 JDBC 的自动提交功能。同时,应用程序一定不要对 XA 连接调用 java.sql.Connection.commit() 或者 java.sql.Connection.rollback()。相反,应用程序应该使用 UserTransaction.begin()、UserTransaction.commit() 和 serTransaction.rollback()。

选择最好的方式
我们讨论了如何用 JDBC 和 JTA 界定事务。每一种方式都有其优点,您需要决定哪一种最适合于您的应用程序。

在最近的许多项目中,我们小组是用 JDBC API 进事务界定来构建 DAO 类的。这些 DAO 类可以总结如下:

事务界定代码嵌入在 DAO 类中。

DAO 类使用 JDBC API 进行事务界定。

调用者不能界定事务。

事务范围局限于单个 JDBC 连接。

JDBC 事务并不总是适合复杂的企业应用程序。如果您的事务要跨越多个 DAO 或者多个数据库,那么下列实现策略也许更合适:

事务用 JTA 界定。

事务界定代码从 DAO 中分离出来。

调用者负责界定事务。

DAO 加入一个全局事务。

JDBC 方式由于其简单性而具有吸引力,JTA 方式提供了更大的灵活性。您所选择的实现将取决于应用程序的特定需求。

日志记录和 DAO
一个良好实现的 DAO 类将使用日志记录来捕捉有关其运行时行为的细节。您可以选择记录异常、配置信息、连接状态、JDBC 驱动程序元数据、或者查询参数。日志对于开发的所有阶段都很有用。我经常在开发时、测试时和生产中分析应用程序日志。

在本节,我将展示一个显示如何将 Jakarta CommonsLogging 加入到 DAO 中的代码示例。在这之前,让我们回顾一下一些基本知识。

选择日志库
许多开发人员使用一种原始格式进行日志记录:System.out.println 和 System.err.println。Println 语句速度快且使用方便,但是它们没有提供全功能的日志记录系统所具有的功能。表 2 列出了 Java 平台的日志库:

表 2. Java 平台的日志库

日志库

开放源代码?

URL

java.util.logging

不是

http://java.sun.com/j2se/

Jakarta Log4j

http://jakarta.apache.org/log4j/

Jakarta Commons Logging

http://jakarta.apache.org/commons/logging.html

java.util.logging 是 J2SE 1.4 平台上的标准 API。不过,大多数开发人员同意 Jakarta Log4j 提供了更多的功能和更大的灵活性。Log4j 优于 java.util.logging 的一点是它同时支持 J2SE 1.3 和 J2SE 1.4 平台。

Jakarta Commons Logging 可以与 java.util.logging 或者 Jakarta Log4j 一同使用。Commons Logging 是一个日志抽象层,它隔离了应用程序与底层日志实现。使用 Commons Logging,您可以通过改变配置文件更换底层日志实现。Commons Logging 在 Jakarta Struts 1.1 和 Jakarta HttpClient2.0 中使用。

一个日志记录示例
清单 7 显示了如何在 DAO 类中使用 Jakarta CommonsLogging:

清单 7. DAO 类中的 Jakarta Commons Logging

import org.apache.commons.logging.*; class  DocumentDAOImpl implements DocumentDAO { static private final Log log =  LogFactory.getLog(DocumentDAOImpl.class); public void deleteDocument(String  id) { // ... log.debug("deleting document: " + id); // ... try { //  ... data operations ... } catch (SomeException ex) { log.error("Unable  to delete document", ex); // ... handle the exception ... } } }

日志记录是所有任务关键型应用程序的重要部分。如果在 DAO 中遇到故障,那么日志通常可以提供判断出错位置的最好信息。将日志加入到 DAO 可以保证您有机会进行调试和故障排除。

DAO 中的异常处理
我们讨论过了事务界定和日志,现在对于如何在数据访问对象上应用它们有了更深入的理解。我们的第三个和最后一个讨论议题是异常处理。遵从几个简单的异常处理指导可以使您的 DAO 更容易使用、更健壮及更易于维护。

在实现 DAO 模式时,考虑以下问题:

DAO 的公共接口中的方法是否抛出检查过的异常?

如果是的话,抛出何种检查过的异常?

在 DAO 实现类中如何处理异常?

在使用 DAO 模式的过程中,我们的小组开发了一些处理异常的原则。遵从这些原则可以极大地改进您的 DAO:

DAO 方法应该抛出有意义的异常。

DAO 方法不应该抛出 java.lang.Exception。java.lang.Exception 太一般化了。它不传递关于底层问题的任何信息。

DAO 方法不应该抛出 java.sql.SQLException。SQLException 是一个低级别的 JDBC 异常。一个 DAO 应该力争封装 JDBC 而不是将 JDBC 公开给应用程序的其余部分。

只有在可以合理地预期调用者可以处理异常时,DAO 接口中的方法才应该抛出检查过的异常。如果调用者不能以有意义的方式处理这个异常,那么考虑抛出一个未检查的(运行时)异常。

如果数据访问代码捕获了一个异常,不要忽略它。忽略捕获的异常的 DAO 是很难进行故障诊断的。

使用链接的异常将低级别的异常转化为高级别的异常。

考虑定义标准 DAO 异常类。Spring Framework (参阅参考资料)提供了很好的一套预定义的 DAO 异常类。

有关异常和异常处理技术的更多信息参阅参考资料。

实现实例: MovieDAO
MovieDAO 是一个展示本文中讨论的所有技术的 DAO:事务界定、日志和异常处理。您可以在参考资料一节中找到 MovieDAO 源代码。代码分为三个包:

daoexamples.exception

daoexamples.movie

daoexamples.moviedemo

DAO 模式的这个实现包含下面列出的类和接口:

daoexamples.movie.MovieDAOFactory

daoexamples.movie.MovieDAO

daoexamples.movie.MovieDAOImpl

daoexamples.movie.MovieDAOImplJTA

daoexamples.movie.Movie

daoexamples.movie.MovieImpl

daoexamples.movie.MovieNotFoundException

daoexamples.movie.MovieUtil

MovieDAO 接口定义了 DAO 的数据操作。这个接口有五个方法,如下所示:

public Movie findMovieById(String id)

public java.util.Collection findMoviesByYear(String year)

public void deleteMovie(String id)

public Movie createMovie(String rating, String year, String, title)

public void updateMovie(String id, String rating, String year, Stringtitle)

daoexamples.movie 包包含 MovieDAO 接口的两个实现。每一个实现使用一种不同的方式进行事务界定,如表 3 所示:

表 3. MovieDAO 实现

MovieDAOImpl

MovieDAOImplJTA

实现 MovieDAO 接口?

通过 JNDI 获得 DataSource?

从 DataSource 获得 java.sql.Connection 对象?

DAO 在内部界定事务?

使用 JDBC 事务?

使用一个 XA DataSource?

参与 JTA 事务?

MovieDAO 演示应用程序
这个演示应用程序是一个名为daoexamples.moviedemo.DemoServlet 的 servlet 类。DemoServlet 使用这两个 Movie DAO 查询和更新表中的电影数据。

这个 servlet 展示了如何将支持 JTA 的 MovieDAO 和 Java 消息服务(Java MessageService)结合到一个事务中,如清单 8 所示。

清单 8. 将 MovieDAO 和 JMS 代码结合到一个事务中

UserTransaction utx =  MovieUtil.getUserTransaction(); utx.begin(); batman =  dao.createMovie("R", "2008", "Batman  Reloaded"); publisher = new MessagePublisher();  publisher.publishTextMessage("I‘ll be back"); dao.updateMovie(topgun.getId(),  "PG-13", topgun.getReleaseYear(), topgun.getTitle());  dao.deleteMovie(legallyblonde.getId()); utx.commit();

要运行这个演示应用程序,需要在应用服务器上配置一个 XA 数据源和一个非 XA 数据源。然后,部署 daoexamples.ear 文件。这个应用程序可以在任何兼容 J2EE 1.3 的应用服务器上运行。参阅参考资料以获得 EAR 文件和源代码。

结束语
正如本文所展示的,实现 DAO 模式需要做比编写低级别的数据访问代码更多的工作。现在,通过选择一个适合您的应用程序的事务界定策略、通过在 DAO 类中加入日志记录,以及通过遵从几项简单的异常处理原则,您可以构建更好的 DAO。

参考资料

从 daoexamples.sourceforge.net上下载 MovieDAO 源代码。

想要学习有关数据访问对象模式的更多内容?可以从核心 J2EE 模式主页开始。

Kyle Brown 的"A stepped approach to J2EE testing with SDAO"(developerWorks,2003 年 3 月)提供了对数据访问对象和 DAO 设计模式的简要介绍。

Dragonslayer 的教程"Create persistent application data with Java Data Objects"(developerWorks,2003 年 7 月)向您展示了如何结合 Struts 与 DAO 模式以用于影响小的企业数据持久性。

Srikanth Shenoy 的"EJB 异常处理的最佳做法"(developerWorks,2002 年 5 月)介绍了异常处理基础和使用 Log4J 进行日志记录。

Java 理论与实践系列从"理解 JTS -- 事务处理简介"开始(developerWorks,2002年3月)提供了对 Java 事务 API 的三部分介绍。

Java Transaction API 是 J2EE 平台的关键部分。

Jakarta Log4j 是 Java 应用程序的世界级日志库。

Jakarta Commons Logging 提供了容易使用的日志抽象层。

Spring Framework 为 JDBC 和事务管理提供了抽象层。此外,这个框架包含标准的 DAO 异常类和 JNDI 帮助器类。

Rod Johnson 的J2EE Design and Development (Wrox Press,2002 年)是每一位 J2EE 开发人员都应该收藏的。本书充满了应用程序设计策略、实用编程技巧和实际的例子。

Josh Bloch 的 Effective Java Programming Language Guide (Addison Wesley,2001 年)展示了异常处理和类库设计的最佳实践。

参阅 Java 技术专区的教程页面,从 developerWorks 获得免费的 Java 技术教程的完整列表。

在 developerWorks Java 技术专区中可以找到数百篇关于 Java 编程的各个方面的文章。

JTA和JTS

Java事务API(JTA:JavaTransaction API)和它的同胞Java事务服务(JTS:Java Transaction Service),为J2EE平台提供了分布式事务服务(distributed transaction)。

  一个分布式事务(distributed transaction)包括一个事务管理器(transaction manager)和一个或多个资源管理器(resource manager)。

  一个资源管理器(resource manager)是任意类型的持久化数据存储。

事务管理器(transaction manager)承担着所有事务参与单元者的相互通讯的责任。

JTA与JDBC

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

XA连接区别于非XA连接。

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

时间: 2024-10-13 22:44:06

jta 知识的相关文章

Java事务处理全解析(八)——分布式事务入门例子(Spring+JTA+Atomikos+Hibernate+JMS)

在本系列先前的文章中,我们主要讲解了JDBC对本地事务的处理,本篇文章将讲到一个分布式事务的例子. 请通过以下方式下载github源代码: git clone https://github.com/davenkin/jta-atomikos-hibernate-activemq.git 本地事务和分布式事务的区别在于:本地事务只用于处理单一数据源事务(比如单个数据库),分布式事务可以处理多种异构的数据源,比如某个业务操作中同时包含了JDBC和JMS或者某个操作需要访问多个不同的数据库. Java

JAVAEE规范基础知识

JavaEE规范基础知识 本人博客文章网址:https://www.peretang.com/basic-knowledge-of-javaee-standard/ JavaEE简介 JavaEE,Java平台企业版,其提供了一个用于开发Web应用和企业应用的标准平台/规范. 意味着,所有d的JavaEE服务器厂商提供的JavaEE 容器/服务器 必然 包含/支持 JavaEE所有规范的实现.使用标准JavaEE规范开发并搭配JavaEE 容器/服务器 可令开发人员专注于业务层面上,而不需要分心

java全面的知识体系结构总结

Java知识体系 目的:为了更好的认识java体系 1.java基础知识 1.1 基础知识 1.1.1 配置环境变量 新建java_home变量(安装目录),值为:C:\Program Files\Java\jdk1.6.0_14:此值为JDK的安装位置. 新建classpath变量(类加载路径),值为:.;%java_home%\lib;%java_home%\lib\tools.jar 修改path变量(使得系统可以在任何路径下识别java命令),值为:%java_home%\bin;%ja

Java基础知识【上】(转载)

http://blog.csdn.net/silentbalanceyh/article/details/4608272 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没有考虑到会坚持往后边写,这次应该是更新该内容.而且很讨厌写基础的东西,内容比较琐碎,而且整理起来总会很多,有可能会打散成两个章节,但是我不保证,有可能一个章节就写完了,所以有时候希望基础的很多内容还是读者自己去看看,我基本保证把基础的内容全部都写出来,见谅.这一个章节写了过后我会把前边那个关于基础类

传智博客(JavaWeb方面的所有知识)听课记录(经典)

一.       JavaWeb基础 第一天: 1.Eclipse详解: (1).Bad versionnumber in .class file:编译器版本和运行(JRE)版本不符合.高的JRE版本兼容低版本的编译器版本. (2).当程序有错误的时候,使用Debug as 运行程序.双击语句设置断点.程序运行到此处停止.点击跳入方法的内部代码.点击跳过,执行下一条代码,点击跳出,跳出方法.观察变量的值,选中变量右击 选择watch. 跳入下一个断点.查看断点,调试完后一定要清除断点.结束运行断

spring事务管理及相关知识

最近在项目中遇到了spring事务的注解及相关知识,突然间感觉自己对于这部分知识只停留在表面的理解层次上,于是乎花些时间上网搜索了一些文章,以及对于源码的解读,整理如下: 一.既然谈到事务,那就先搞清到底什么是事务,或者说,Spring事务管理中的事务到底是指什么? 1.事务(Transaction),通常是指数据库的事务,在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit),例如insert .update.delete等,事务是恢复和并发控制的基本单位. 2.事务

hibernate必须知道的知识

Hibernate经典知识:   1.Hibernate工作原理及为什么要用?   1.       答:hibernate,通过对jdbc进行封装,对 java类和关系数据库进行mapping,实现了对关系数据库的面向对象方式的操作. 1.对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码. hibernate的性能非常好,因为它是个轻量级框架. 1.它支持各种关系数据库,从一对一到多对多的各种复杂关系. 1).读取并解析配置文件 2).读取并解析映射信息,创建Sessi

事务相关知识(传播特性,隔离级别,锁)

上接 : EJB事务控制(CMT和BMT两种方式以及JTA事务) 上篇代码: @TransactionAttribute(TransactionAttributeType.REQUIRED)  //设置事务的传播特性为required 上篇文章为什么设置传播特性为: required? 事务的传播特性有7个: 1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务.如果没有事务则开启       2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持

沉淀,再出发:Java基础知识汇总

沉淀,再出发:Java基础知识汇总 一.前言 不管走得多远,基础知识是最重要的,这些知识就是建造一座座高楼大厦的基石和钢筋水泥.对于Java这门包含了编程方方面面的语言,有着太多的基础知识了,从最初的语法,对象的定义,类.接口.继承.静态.动态.重载.覆盖这些基本的概念和使用方法,到稍微高级一点的多线程,文件读写,网络编程,GUI使用,再到之后的反射机制.序列化.与数据库的结合等高级一点的用法,最后将设计模式应用其中,产生了一个个新的概念,比如Spring.Spring MVC.Hibernat