Spring对JTA的支持
引言:
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的支持的更多相关文章
- 传统Spring配置JTA 实现多数据源事务的统一管理
分布式事务是指事务的参与者.支持事务的服务器.资源管理器以及事务管理器分别位于分布系统的不同节点之上,在两个或多个网络计算机资源上访问并且更新数据,将两个或多个网络计算机的数据进行的多次操作作为一个整 ...
- java 利用spring JavaMailSenderImpl发送邮件,支持普通文本、附件、html、velocity模板
java 利用spring JavaMailSenderImpl发送邮件,支持普通文本.附件.html.velocity模板 博客分类: Java Spring 本文主要介绍利用JavaMailS ...
- Spring AOP和AspectJ支持
学了Spring之后发现我都不知道java为何物-- 在这一章中有好几节,讲的切面编程 第一节:在项目中启用Spring的AspectJ注解支持 第二节:用AspectJ注解声明aspect 第三节: ...
- Spring使用拦截器支持国际化(转)
Spring使用拦截器支持国际化很方便,使用时只需要两个步骤: 一.spring配置 具体配置方式如下: <!-- 资源文件绑定器,文件名称:messages.properties(没有找到时的 ...
- Spring对远程服务的支持
Java程序有以下的远程调用技术选择: 远程过程调用(RPC)是同步的,客户端在服务器端返回结果之前将一直被阻塞. 各种技术适用的场景如下: 典型的RMI开发的过程如下: 定义一个接口,用于客户端和服 ...
- 1.Spring对JDBC整合支持
1.Spring对JDBC整合支持 Spring对DAO提供哪些支持 1)Spring对DAO异常提供统一处理 2)Spring对DAO编写提供支持的抽象类 3)提高编程效率,减少DAO编码量 Spr ...
- [Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction
1.Spring中的数据库支持 把具有相同功能的代码模板抽取到一个工具类中.2.关于jdbc template的应用 jdbcTemplate模板操作类,把访问jdbc的模板抽取到template中, ...
- Spring Boot 添加JSP支持【转】
Spring Boot 添加JSP支持 大体步骤: (1) 创建Maven web project: (2) 在pom.xml文件添加依赖: (3) ...
- 8 -- 深入使用Spring -- 8...1 Spring提供的DAO支持
8.8.1 Spring提供的DAO支持. DAO模式是一种标准的Java EE设计模式,DAO模式的核心思想是,所有的数据库访问都通过DAO组件完成,DAO组件封装了数据库的增.删.查.改等原子操作 ...
- 8 -- 深入使用Spring -- 2... Spring的“零配置”支持
8.2 Spring的“零配置”支持 Spring支持使用Annotation来代替XML配置文件.
随机推荐
- 一个操作系统的设计与实现——第19章 IA32-e模式
19.1 64位段描述符与GDT 在32位操作系统中,我们使用的是平坦模型而非分段模型,从而,段描述符的段基址和段限长均成了摆设.在64位模式下,就连CPU也淘汰了分段模型,转而固定使用平坦模型. 6 ...
- Seata 1.3.0 Oracle 回滚测试验证 报错 ORA-02289: 序列不存在
使用Seata 1.3.0版本,测试A服务调用B服务,且A方法中,手动写了一个异常,测试是否正常回滚(Mysql已经测试过) 发现报错:ORA-02289: 序列不存在 一看就是undo_log这张表 ...
- ASP.NET Core – Try Preview
前言 .NET 7 已经来到 RC 阶段了. 通常 RC 就是我们 (写库的人) 要入场的时候了. 有发现 Bug 要尽可能在这段期间提交. 不然后患无穷. 这篇主要就是来讲讲如果测试 RC 版本的 ...
- SimpleAISearch:C# + DuckDuckGo 实现简单的AI搜索
最近AI搜索很火爆,有Perplexity.秘塔AI.MindSearch.Perplexica.memfree.khoj等等. 在使用大语言模型的过程中,或许你也遇到了这种局限,就是无法获取网上最新 ...
- Windows右下角时间显示到秒(改注册表)
事件起因: 由于京东秒杀,要准点抢购,于是想着能不能把Windows右下角的时间显示到秒,于是在网上查了一下,修改注册表即可 解决办法: 新建一个 ShowSecondsInSystemClock ...
- 【赵渝强老师】MySQL高可用架构:MHA
MHA(Master HA)是一款开源的 MySQL 的高可用程序,它为 MySQL 主从复制架构提供了 automating master failover 功能.MHA 在监控到 master 节 ...
- Windows应急响应-Auto病毒
目录 应急背景 分析样本 开启监控 感染病毒 查看监控 分析病毒行为 autorun.inf分析 2.异常连接 3.进程排查 4.启动项排查 查杀 1.先删掉autorun.inf文件 2.使用xue ...
- 2022年2月国产数据库排行榜: OceanBase“三连增”重夺探花,GaussDB实现本月最大涨幅引期待
寒辞去冬雪,暖带入春风.2022年2月,虎年开年的国产数据库流行度排行榜已在墨天轮社区发布,本月共有195个数据库参与排名.排名前十位的数据库分数增减幅度较大,整体排名略有波动. 首先,我们来看看排行 ...
- C# 中的四种整形数据
// C# 中有四种整数类型 byte short int long byte bMax = byte.MaxValue; /// 255 最大值 byte bMin = byte.MinValue; ...
- 49.var声明的函数和function声明的函数谁的优先级更高
function 声明函数的优先级更高 : 因为 function声明函数的时候,是在代码解析之前赋值给变量,此时就已经可以调用了 : 但是var 声明的函数,要在代码运行阶段才会赋值给变量,这个时候 ...