引言:

  Spring 通过AOP技术可以让我们在脱离EJB的情况下享受声明式事务的丰盛大餐。

  通过配合使用ObjectWeb的JOTM开源项目,在不需要Java EE应用服务器的情况下,Spring也可以提供JTA事务。

Sping对JTA支持的三种方式:

  1. 直接集成JOTM提供JTA事务管理(无应用服务器支持,常用于单元测试)

  2. 引用应用服务器(如Tomcat)的JNDI数据源,间接实现JTA事务管理

  3. 使用特定于应用服务器的事务管理器,使用JTA事务的高级功能(Weblogic,Websphere)

1. JOTM直接集成

1.1. 将JOTM以下类库添加到类路径中: 

  jotm.jar 

  xapool.jar 

  jotm_jrmp_stubs.jar 

  jta-spec1_0_1.jar 

  connector-1_5.jar

1.2. 编写JOTM配置文件,放到类路径下 

  carol.properties 

  #JNDI调用协议 

  carol.protocols=jrmp 

  #不使用CAROL JNDI封装器 

  carol.start.jndi=false 

  #不启动命名服务器 

  carol.start.ns=false

1.3. 在MySQL上建立两个数据库 

  在MySQL数据库中运行SQL脚本,建立topicdb和postdb两个数据库,

  在topicdb数据库中创建t_topic表,在postdb数据库中创建t_post表。

  我们希望在这两个数据库上进行JTA事务。

1.4. 在Spring配置文件中配置JOTM,并实现具体业务类

代码清单 1 applicationContext-jta.xml

<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" />
①JOTM本地实例 ②JTA事务管理器
<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction" ref="jotm" />
②-1:指定userTransaction属性
</bean>
③XAPool配置,内部包含了一个XA数据源,对应topicdb数据库
<bean id="topicDS" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"
destroy-method="shutdown">
<property name="dataSource">
③-1:内部XA数据源
<bean class="org.enhydra.jdbc.standard.StandardXADataSource"
destroy-method="shutdown">
<property name="transactionManager" ref="jotm" />
<property name="driverName" value="com.MySQL.jdbc.Driver" />
<property name="url" value="jdbc:MySQL://localhost:3309/topicdb" />
</bean>
</property>
<property name="user" value="root" />
<property name="password" value="1234" />
</bean>
④按照③相似的方式配置另一个XAPool,对应postdb数据库,
<bean id="postDS" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"
destroy-method="shutdown">
<property name="dataSource">
<bean class="org.enhydra.jdbc.standard.StandardXADataSource"
destroy-method="shutdown">
<property name="transactionManager" ref="jotm" />
<property name="driverName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3309/postdb" />
</bean>
</property>
<property name="user" value="root" />
<property name="password" value="1234" />
</bean>
⑤配置访问topicDB数据源的Spring JDBC模板
<bean id="topicTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="topicDS" />
</bean>
⑥配置访问postDB数据源的Spring JDBC模板
<bean id="postTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="postDS" />
</bean>
⑦基于topicTemplate数据源的topicDao
<bean id="topicDao" class="com.baobaotao.dao.jdbc.TopicJdbcDao">
<property name="jdbcTemplate" ref="topicTemplate" />
</bean>
⑧基于postTemplate数据源的postDao
<bean id="postDao" class="com.baobaotao.dao.jdbc.PostJdbcDao">
<property name="jdbcTemplate" ref="postTemplate" />
</bean>
⑨进行跨数据库JTA事务的业务类
<bean id="bbtForum" class="com.baobaotao.service.impl.BbtForumImpl">
<property name="topicDao" ref="topicDao" />
<property name="postDao" ref="postDao" />
</bean>
⑩对BbtForumImpl业务类中的@Transaction注解进行驱动
<tx:annotation-driven transaction-manager="txManager" />

代码清单 2 BbtForumImpl

package com.baobaotao.service.impl;  

import org.springframework.transaction.annotation.Transactional;
import com.baobaotao.dao.PostDao;
import com.baobaotao.dao.TopicDao;
import com.baobaotao.domain.Forum;
import com.baobaotao.domain.Topic;
import com.baobaotao.service.BbtForum; @Transactional
//①事务注解,以便Spring动态织入事务管理功能
public class BbtForumImpl implements BbtForum {
private TopicDao topicDao;
private PostDao postDao; public void addTopic(Topic topic) throws Exception {
//②将方法将被施加JTA事务的增强
topicDao.addTopic(topic);
postDao.addPost(topic.getPost());
}
}

1.5. 在Spring中运行测试

package com.baobaotao.service;  

import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
… public class TestBbtForumJta extends AbstractDependencyInjectionSpringContextTests{
private BbtForum bbtForum;
private final Logger logger = Logger.getLogger(getClass()); public void setBbtForum(BbtForum bbtForum) {
this.bbtForum = bbtForum;
} protected String[] getConfigLocations() {
return new String[]{"classpath:applicationContext-jta.xml"};
} public void testAddPost() throws Exception{
logger.info("begin........");
Topic topic = new Topic();
topic.setTopicTitle("Title -pfb"); Post post = new Post();
post.setPostText("post content -pfb");
topic.setPost(post); bbtForum.addTopic(topic);
//①使用了JTA事务的业务方法
logger.info("end........");
}
}

2. Spring引用Tomcat的 JTA事务

  Tomcat是Servlet容器,但它提供了JNDI的实现,

  因此用户可以象在Java EE应用程序服务器中一样,在Tomcat中使用JNDI查找JDBC数据源。

  在事务处理方面,Tomcat本身并不支持JTA,但是可以通过集成JOTM达到目的。

  (测试环境:Tomcat 5.5+JOTM 2.3)

2.1. 添加所需的JAR文件 

  将JOTM以下类包添加到<Tomcat安装目录>/common/lib目录中: 

    jotm.jar 

    jotm_jrmp_stubs.jar 

    jotm_iiop_stubs.jar 

    ow_carol.jar 

    jta-spec1_0_1.jar 

    jts1_0.jar 

    objectweb-datasource.jar 

    xapool.jar 

    howl.jar 

    connector-1_5.jar 

  同时,还需要添加相应数据库的JDBC驱动类包,例如MySQL的mysql.jar。

2.2. 配置JOTM 

  新建一个carol.properties配置文件,放置到<Tomcat安装目录>/common/classes目录下,配置文件内容如下:

    #JNDI调用协议 

    carol.protocols=jrmp 

    # 本地RMI调用 

    carol.jvm.rmi.local.call=true 

    # 不使用CAROL的JNDI封装器 

    carol.start.jndi=false 

    # 不启用命名服务器 

    carol.start.ns=false 

    # 命名工厂类 

    carol.jndi.java.naming.factory.url.pkgs=org.apache.naming 

    将carol.start.jndi设置为false,让JOTM不使用CAROL JNDI wrapper,从而可以避免类装载错误的发生。

2.3. 配置Tomcat环境,配置JNDI的数据源 

  在<Tomcat安装目录>/conf/context.xml文件中添加以下内容:

<!-- ①:JNDI数据源 -->
<Resource name="jdbc/topicDS" auth="Container" type="javax.sql.DataSource"
factory="org.objectweb.jndi.DataSourceFactory"
username="root"
password="1234"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3309/topicdb"
maxActive="30"
maxIdle="30" /> <!-- ①:JNDI数据源 -->
<Resource name="jdbc/postDS" auth="Container" type="javax.sql.DataSource"
factory="org.objectweb.jndi.DataSourceFactory"
username="root"
password="1234"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3309/postdb"
maxActive="30"
maxIdle="30" /> <!-- ②JOTM JTA事务管理 -->
<Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60" />

4. Spring中相应的配置

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
  http://www.springframework.org/schema/jee
  http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"> <jee:jndi-lookup id="topicDS" jndi-name="java:comp/env/jdbc/topicDS" />
<jee:jndi-lookup id="postDS" jndi-name="java:comp/env/jdbc/postDS" />
<bean id="topicTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="topicDS" />
</bean>
<bean id="postTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="postDS" />
</bean>
<bean id="topicDao" class="com.baobaotao.dao.jdbc.TopicJdbcDao">
<property name="jdbcTemplate" ref="topicTemplate" />
</bean>
<bean id="postDao" class="com.baobaotao.dao.jdbc.PostJdbcDao">
<property name="jdbcTemplate" ref="postTemplate" />
</bean>
<bean id="bbtForum" class="com.baobaotao.service.impl.BbtForumImpl">
<property name="topicDao" ref="topicDao" />
<property name="postDao" ref="postDao" />
</bean> <bean id="txManager"
  class="org.springframework.transaction.jta.JtaTransactionManager" />
<tx:annotation-driven transaction-manager="txManager" />
</beans>

3. 在特定应用服务器使用JTA

BEA WebLogic 

  在一个使用WebLogic 7.0、8.1或更高版本的环境中,你一般会优先选用特定于WebLogic的 WebLogicJtaTransactionManager 类

  来取代基础的 JtaTransactionManager 类。

  因为在WebLogic环境中,该类提供了对Spring事务定义的完全支持,超过了标准的JTA语义。

  你可以使用以下的配置达到目的:

<bean id="txManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"/> 

  它的特性包括:支持事务名,支持为每个事务定义隔离级别,以及在任何环境下正确地恢复事务的能力。

IBM WebSphere 

  在WebSphere 5.1、5.0和4.x环境下,你可以使用Spring的 WebSphereTransactionManagerFactoryBean 类。

  这是一个工厂类,通过WebSphere的 静态访问方法(每个版本的WebSphere中都不同)获取到JTA TransactionManager 实例。

  一旦通过工厂bean获取到JTA TransactionManager 实例,

  就可以使用该实例装配一个Spring的 JtaTransactionManager bean,

  它封装了JTA UserTransaction,提供增强的事务语义。

<bean id="wsJtaTm"
class="org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean" />
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager ref=" wsJtaTm " />
<!--①引用WebSphere的JTA事务管理器-->
</bean>

名称解释:

  JOTM(Java Open Transaction Manager)是ObjectWeb的一个开源JTA实现,

  它本身也是开源应用程序服务器JOnAS(Java Open Application Server)的一部分,

  为其提供JTA分布式事务的功能。

参考:

JTA事务管理(一)http://mavin.zhou.blog.163.com/blog/static/114522435200971822334475/

JTA事务管理(二)http://mavin.zhou.blog.163.com/blog/static/114522435200971822912342/

其它:

JTA集成JOTM或Atomikos配置分布式事务(Tomcat应用服务器) http://kb.cnblogs.com/a/2012014/

Spring对JTA的支持的更多相关文章

  1. 传统Spring配置JTA 实现多数据源事务的统一管理

    分布式事务是指事务的参与者.支持事务的服务器.资源管理器以及事务管理器分别位于分布系统的不同节点之上,在两个或多个网络计算机资源上访问并且更新数据,将两个或多个网络计算机的数据进行的多次操作作为一个整 ...

  2. java 利用spring JavaMailSenderImpl发送邮件,支持普通文本、附件、html、velocity模板

    java 利用spring JavaMailSenderImpl发送邮件,支持普通文本.附件.html.velocity模板 博客分类: Java Spring   本文主要介绍利用JavaMailS ...

  3. Spring AOP和AspectJ支持

    学了Spring之后发现我都不知道java为何物-- 在这一章中有好几节,讲的切面编程 第一节:在项目中启用Spring的AspectJ注解支持 第二节:用AspectJ注解声明aspect 第三节: ...

  4. Spring使用拦截器支持国际化(转)

    Spring使用拦截器支持国际化很方便,使用时只需要两个步骤: 一.spring配置 具体配置方式如下: <!-- 资源文件绑定器,文件名称:messages.properties(没有找到时的 ...

  5. Spring对远程服务的支持

    Java程序有以下的远程调用技术选择: 远程过程调用(RPC)是同步的,客户端在服务器端返回结果之前将一直被阻塞. 各种技术适用的场景如下: 典型的RMI开发的过程如下: 定义一个接口,用于客户端和服 ...

  6. 1.Spring对JDBC整合支持

    1.Spring对JDBC整合支持 Spring对DAO提供哪些支持 1)Spring对DAO异常提供统一处理 2)Spring对DAO编写提供支持的抽象类 3)提高编程效率,减少DAO编码量 Spr ...

  7. [Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction

    1.Spring中的数据库支持 把具有相同功能的代码模板抽取到一个工具类中.2.关于jdbc template的应用 jdbcTemplate模板操作类,把访问jdbc的模板抽取到template中, ...

  8. Spring Boot 添加JSP支持【转】

    Spring Boot 添加JSP支持 大体步骤: (1)            创建Maven web project: (2)            在pom.xml文件添加依赖: (3)     ...

  9. 8 -- 深入使用Spring -- 8...1 Spring提供的DAO支持

    8.8.1 Spring提供的DAO支持. DAO模式是一种标准的Java EE设计模式,DAO模式的核心思想是,所有的数据库访问都通过DAO组件完成,DAO组件封装了数据库的增.删.查.改等原子操作 ...

  10. 8 -- 深入使用Spring -- 2... Spring的“零配置”支持

    8.2 Spring的“零配置”支持 Spring支持使用Annotation来代替XML配置文件.

随机推荐

  1. Goby漏洞发布 | CVE-2024-38856 Apache OFbiz /ProgramExport 命令执行漏洞【已复现】

    漏洞名称:Apache OFbiz /ProgramExport 命令执行漏洞(CVE-2024-38856) English Name:Apache OFbiz /ProgramExport Com ...

  2. CSS – Tailwind CSS

    前言 很多时候 CSS 未必是需要管理的, 比如做网站, Landing Page (类似宣传单). 很多时候做了 > 用了 > 丢 > 再做新的. 它没有 "维护&quo ...

  3. SQL Server – 我常用语句

    前言 旧没用又忘记了, 又没有 intellisense, 记入这里吧. Reset Auto Increment DBCC CHECKIDENT ('TableName'); -- check cu ...

  4. EF Core – 乐观并发

    前言 之前写过 EF Core 悲观并发, 这篇主要讲一下乐观并发. 乐观并发的机制可以看这篇. Why Need This? 如果你用 EF Core 做数据管理, 建议你每个 Entity 都配置 ...

  5. Codes 开源研发项目管理平台——创新的敏捷测试解决方案

    前言 Codes 是国内首款重新定义 SaaS 模式的开源项目管理平台,支持云端认证.本地部署.全部功能开放,并且对 30 人以下团队免费.它通过整合迭代.看板.度量和自动化等功能,简化测试协同工作, ...

  6. 学好QT框架之后可以做什么工作?QT技术框架现代化行业大型复杂应用的经典成功案例

    简介 本文粗略的介绍了QT框架的软件开发技术生态体系的全球影响力:QT框架在文字办公领域.CAD三维图形领域.Linux操作系统领域.物联网领域.汽车电子领域以及数字医疗领域等现代化行业的大型复杂应用 ...

  7. Windows系统无法打开‘’网络发现‘’功能

    Windows10无法开启网络发现 解决办法: 1. services.msc 2. 开启 SSDP Discovery ,设置 启动类型为 自动 ,服务状态为 启动 Windows7 无法开启网络发 ...

  8. Windows下使用Wireshark分析USB通信

    WireShark中对USB数据捕获 可以监视与主机连接的usb数据. usb设备是三段地址描述,例如1.15.1,第一个是总线,第二个是设备地址,第三个是端口. USB数据抓包分析 这些是鼠标的数据 ...

  9. 什么是 DOM

    百度: DOM 定义:文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口.它是一种与平台和语言无关的应用程序接口(API),它可 ...

  10. Javascript的基本数据类型和引用数据类型有哪些?null 和 undefined的区别

    基本数据类型 : number string boolean null undefined 引用数据类型: object   -->  function array function and a ...