JTA事务管理--配置剖析
概述
【IT168 专稿】Spring 通过AOP技术可以让我们在脱离EJB的情况下享受声明式事务的丰盛大餐,脱离Java EE应用服务器使用声明式事务的道路已经畅通无阻。但是很大部分人都还认为脱离Java EE应用服务器就无法使用JTA事务,这是一个误解。其实,通过配合使用ObjectWeb的JOTM开源项目,不需要Java EE应用服务器,Spring也可以提供JTA事务。
正因为AOP让Spring拥有了脱离EJB容器的声明式事务能力,而JOTM让我们在脱离Java EE应用服务器下拥有JTA事务能力。所以,人们将AOP和JOTM称为Java软件开发的两个圣杯。
本文将讲解Spring在不同环境下提供JTA事务的配置过程,这包括:Spring中直接集成JOTM提供JTA事务管理、将JOTM集成到Tomcat中,Spring通过引用Tomcat JNDI数据源提供JTA事务管理、引用其它功能完善JavaEE应用服务器所提供的JTA事务管理。
通过集成JOTM,直接在Spring中使用JTA事务
JOTM(Java Open Transaction Manager)是ObjectWeb的一个开源JTA实现,它本身也是开源应用程序服务器JOnAS(Java Open Application Server)的一部分,为其提供JTA分布式事务的功能。
Spring 2.0附带的依赖类库中虽然包含jotm类库,但是并不完整,你可以到http://jotm.objectweb.org下载完全版的JOTM。
Spring为JOTM提供了一个org.springframework.transaction.jta.JotmFactoryBean支持类,通过该支持类可以方便地创建JOTM本地实例。
下面,我们通过配置,使上节中BbtForumImpl#addTopic()方法工作在JTA事务的环境下。addTopic()内部使用两个DAO类(TopicDao和PostDao)分别访问不同数据库中的表。通过下面的步骤说明了使addTopic()方法拥有JTA事务的整个过程:
1. 将JOTM以下类库添加到类路径中:
jotm.jar
xapool.jar
jotm_jrmp_stubs.jar
jta-spec1_0_1.jar
connector-1_5.jar
2. 编写JOTM配置文件,放到类路径下
carol.properties
#JNDI调用协议
carol.protocols=jrmp
#不使用CAROL JNDI封装器
carol.start.jndi=false
#不启动命名服务器
carol.start.ns=false
3. 在MySQL上建立两个数据库
在MySQL数据库中运行SQL脚本,建立topicdb和postdb两个数据库,在topicdb数据库中创建t_topic表,在postdb数据库中创建t_post表。我们希望在这两个数据库上进行JTA事务。
4. 在Spring配置文件中配置JOTM
代码清单 1 applicationContext-jta.xml
…
<!--①JOTM本地实例 -->
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" />
<!--②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" />
首先,我们在①处通过Spring所提供的JotmFactoryBean创建一个本地JOTM实例,该实例同时实现了 javax.transaction.UserTransaction和javax.transaction.TransactionManager接口,它可以和ObjectWeb的XAPool一起工作。
JTA事务管理器通过userTransaction属性引用本地JOTM实例,Spring的JtaTransactionManager会自动探测到传入的javax.transaction.UserTransaction引用也实现了javax.transaction.TransactionManager,所以我们无需再配置JtaTransactionManager的transactionManager属性,如②所示。
在Spring中配置JOTM的另一个关键问题是配置XAPool,支持JTA事务的数据源必须封装成XAPool。首先,我们通过org.enhydra.jdbc.standard.StandardXADataSource 配置一个XA数据源,它指向topicdb数据库,如③-1所示。而后,通过org.enhydra.jdbc.pool.StandardXAPoolDataSource将其封装成一个XAPool,如③所示。按照相同的方式,配置指向postdb数据库的XAPool,如④所示。
接下来的配置就顺理成章了,分别使用Spring JDBC的模板类配置DAO类,然后再配置引用DAO类的业务类。关于Spring JDBC的详细内容,参见第10章的内容。
这里,我们使用@Transaction注解对业务类BbtForumImpl进行事务声明,所以通过<tx:annotation-driven/>对此进行驱动,BbtForumImpl的代码如下所示:
代码清单 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());
}
}
BbtForumImpl将Dao类组织起来,PostDao和TopicDao分别访问不同数据库中表,通过Spring注解驱动事务切面的增强后,它们将工作于同一个JTA事务中。
5. 在Spring中运行测试
代码清单 3 TestBbtForumJta
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........");
}
}
通过Spring测试类AbstractDependencyInjectionSpringContextTests的支持,很容易编写一个测试类,对启用了JTA事务的BbtForum#addTopic()方法进行测试。建议你将Log4J设置为DEBUG,这样就可以通过丰富的输出日志观测到JTA事务的执行情况。运行这个测试类后,你将可以看到JTA事务被正确实施。
JTA事务管理--配置剖析的更多相关文章
- JTA事务管理--配置剖析(二)
Spring引用Tomcat的 JTA事务 Tomcat是Servlet容器,但它提供了JNDI的实现,因此用户可以象在Java EE应用程序服务器中一样,在Tomcat中使用JNDI查找JD ...
- springboot多数据源+jta事务管理配置
1.创建一个maven项目,导入相关配置: <?xml version="1.0" encoding="UTF-8"?> <project x ...
- spring,mybatis事务管理配置与@Transactional注解使用[转]
spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...
- JTA事务管理
何为分布式事务 一个事务包含多个操作,多个操作操作了多个数据源,这样的事务称为分布式事务 和普通事务的区别 单一数据源,事务管理可以借助数据源本地事务完成,实现简单 分布式事务之困难:不可简单的借助数 ...
- 事务管理配置与@Transactional注解使用
spring,mybatis事务管理配置与@Transactional注解使用 概述 事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性. Spring Framewor ...
- spring,mybatis事务管理配置与@Transactional注解使用
spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是 ...
- Spring事务管理配置以及异常处理
Spring事务管理配置: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...
- [转]Spring的事务管理难点剖析(1):DAO和事务管理的牵绊
原文地址:http://stamen.iteye.com/blog/1441758 有些人很少使用Spring而不使用Spring事务管理器的应用,因此常常有人会问:是否用了Spring,就一定要用S ...
- spring3.0事务管理配置
转载:http://war-martin.iteye.com/blog/1396335 第一种配置方法:基于XML的事务管理 这种方法不需要对原有的业务做任何修改,通过在XML文件中定义需要拦截方法的 ...
随机推荐
- java基础知识回顾之java集合类-Properties集合
/** java.lang.Object |--java.util.Dictionary<K,V> |--java.util.Hashtable<Object,Obje ...
- ubuntu12.10+NDK r9 编译 ffmpeg 的一些参考资料Perhaps you should add the directory containing `libssl.pc'
首先入门级的 编译宝典: https://trac.ffmpeg.org/wiki/CompilationGuide/Android http://www.roman10.net/how-to-bui ...
- Android 注意在finish Activity之后也要停止正在运行的请求
如果在一个Activity里面启动了网络请求,而在这个网络请求还没返回结果的时候,如果Activity被结束了,则我们需要写如下代码作为防守: @Override public void onPost ...
- 李洪强iOS开发之Foundation框架—结构体
Foundation框架—结构体 一.基本知识 Foundation—基础框架.框架中包含了很多开发中常用的数据类型,如结构体,枚举,类等,是其他ios框架的基础. 如果要想使用foundation框 ...
- Callable与Future的简单介绍
Callable与Future的介绍 Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类 ...
- JavaWeb项目开发案例精粹-第2章投票系统-006view层
1.index.jsp <%@ page language="java" import="java.util.*" pageEncoding=" ...
- 与Google轻轻地擦肩而过
第一集 因为那几年三天两头往硅谷里飞,所以我实在记不清这个故事到底是发生在98年还是99年夏天某日的一个下午. 那天我和Excite.com的创始人Mark V. H.在Palo Alto的一家餐厅共 ...
- Arcgis Engine最短路径分析
ArcEngine 最短路径分析(源码) using System; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Geometry; using ESRI ...
- WCF入门(十一)---WCF安全
一个强大的WCF服务安全系统,拥有两种安全模式或级别预期的客户端可以访问的服务.这是常见的分布式事务的安全威胁正在放缓,在很大程度上由WCF决定. 关键的安全功能 WCF服务有四个主要的安全功能,如下 ...
- VS2010/MFC编程入门教程之目录和总结
鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够.以此教程的知识为基础,学习VS2010/MFC较为深入的内容 ...