Spring 中集成 JOTM 配置 JTA 事务:
假如业务中要用到多个数据库,我们希望在业务方法中,当对某一个数据库的数据表进行操作的事务失败并回退(rollback),另外某一个数据库的数据表的操作事务也要回退,但应用一般的事务管理达不到这样的事务管理效果,这就需要实现 JTA 事务管理了。
这里我们在SPring中集成 Object web 的一个开源JTA实现JOTM (可以在http://jotm.objectweb.org下载完整版) 来实现JTA事务管理。
1、将必须的类包放入类路径中:
jotm.jar, xapool.jar, jotm_jrmp_stubs.jar, jta-spect1_0_1.jar, connector-1_5.jar等等。
2、编写JOTM配置文件carol.properties,将其放到类路径下:
Java代码
#JNDI调用协议
carol.protocols=jrmp
#不使用CAROL JNDI封装器
carol.start.jndi=false
#不启动命名服务器
carol.start.ns=false
3、在MYSQL中创建两个数据库 "jtatesta","jtatestb":
Java代码
CREATE DATABASE IF NOT EXISTS jtatesta;
USE jtatesta;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`user_id` int(10) unsigned NOT NULL auto_increment,
`user_name` varchar(45) NOT NULL,
`user_password` varchar(45) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
INSERT INTO `user` (`user_id`,`user_name`,`user_password`) VALUES
(1,'tufu','tufu');
CREATE DATABASE IF NOT EXISTS jtatestb;
USE jtatestb;
DROP TABLE IF EXISTS `grade`;
CREATE TABLE `grade` (
`grade_id` int(10) unsigned NOT NULL auto_increment,
`user_id` int(10) unsigned NOT NULL,
`grade` double NOT NULL,
PRIMARY KEY (`grade_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
INSERT INTO `grade` (`grade_id`,`user_id`,`grade`) VALUES
(1,0,100);
4、域对象、数据访问类和其他事务管理的一样,如:
Java代码
//Domain对象User.java:
package com.domain;
import java.io.Serializable;
public class User implements Serializable {
private int user_id;
private String user_name;
private String user_password;
......//省略set、get方法
}
//Domain对象Grade.java:
package com.domain;
import java.io.Serializable;
public class Grade implements Serializable{
private int grade_id;
private User user;
private double grade;
.....//省略set、get方法
}
应用Spring JDBC的DAO:(省略DAO接口)
//UserJdbcDao.java:
package com.dao.jdbc;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.dao.UserDao;
import com.domain.User;
public class UserJdbcDao extends JdbcDaoSupport implements UserDao{
public void addUser(User user){
String SQL = "INSERT INTO user(user_id,user_name,user_password) VALUES(?,?,?)";
Object[] params = new Object[]{
user.getUser_id(),user.getUser_name(),user.getUser_password()
};
this.getJdbcTemplate().update(SQL, params);
}
}
//GradeJdbcDao.java:
package com.dao.jdbc;
import com.dao.GradeDao;
import com.domain.Grade;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class GradeJdbcDao extends JdbcDaoSupport implements GradeDao{
public void addGrade(Grade grade){
final String SQL = "INSERT INTO grade(user_id,grade) VALUES(?,?)";
Object[] params = new Object[]{
grade.getUser().getUser_id(),grade.getGrade()
};
this.getJdbcTemplate().update(SQL, params);
}
}
5、应用了JTA事务管理的业务类(省略了接口),用@Transactional注解标注,以在配置文件中可以用<tx:annotation-driven>注解驱动自动进行事务增强:
Java代码
package com.service.impl;
import com.dao.GradeDao;
import com.dao.UserDao;
import com.domain.*;
import org.springframework.transaction.annotation.Transactional;
import com.service.MyService;
@Transactional
public class MyServiceImpl implements MyService {
private UserDao userDao;
private GradeDao gradeDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
public void setGradeDao(GradeDao gradeDao){
this.gradeDao = gradeDao;
}
@Transactional(readOnly=false)
public void addGrade(User user,Grade grade){
//假如希望两个添加数据的事务,其中有一个添加失败时,均回滚,
//由于两个操作是在两个不同的数据库上进行的,故要JTA事务来进行管理
//否则,将会出现添加一个,回滚一个的情形
gradeDao.addGrade(grade);
userDao.addUser(user);
}
}
6、spring为JOTM提供了一个org.springframework.transaction.jta.JotmFactoryBean 支持类,可以用其方便地创建本地JOTM实例。
具体的配置文件app_jta.xml如下:
Xml代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsp="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsp:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!--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"/><!--指定userTransaction属性引用JOTM本地实例-->
</bean>
<!--XAPool配置,内部包含了一XA数据源,对应了数据库jtatesta
支持JTA事务的数据源,必须封装成XAPool-->
<bean id="jtaTestADS" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"
destroy-method="shutdown">
<property name="dataSource"><!--内部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/jtatesta"/>
</bean>
</property>
<property name="user" value="root"/>
<property name="password" value="885123"/>
</bean>
<!--类似地,对应了数据库jtatestb的XAPool配置,内部包含了一XA数据源-->
<bean id="jtaTestBDS" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"
destroy-method="shutdown">
<property name="dataSource"><!--内部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/jtatestb"/>
</bean>
</property>
<property name="user" value="root"/>
<property name="password" value="885123"/>
</bean>
<!--分别配置访问jtaTestADS、jtaTestBDS数据源的Spring JDBC模板-->
<bean id="jtaTestATemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="jtaTestADS"/>
</bean>
<bean id="jtaTestBTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="jtaTestBDS"/>
</bean>
<!--分别配置基于模板jtaTestADS,jtaTestBDS的DAO-->
<bean id="userDao" class="com.dao.jdbc.UserJdbcDao">
<property name="jdbcTemplate" ref="jtaTestATemplate"/>
</bean>
<bean id="gradeDao" class="com.dao.jdbc.GradeJdbcDao">
<property name="jdbcTemplate" ref="jtaTestBTemplate"/>
</bean>
<!--跨数据库的JTA事务的业务类-->
<bean id="myService" class="com.service.impl.MyServiceImpl">
<property name="userDao" ref="userDao"/>
<property name="gradeDao" ref="gradeDao"/>
</bean>
<!--注解事务驱动-->
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
</beans>
7、测试main方法:
Java代码
import com.service.MyService;
import com.service.impl.MyServiceImpl;
import com.domain.*;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestMain {
public static void main(String args[]){
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext("beans_jta.xml");
MyService ms = (MyServiceImpl)ctx.getBean("myService");
User user = new User();
//特意添加一个重复的主键,以使添加user的事务失败并回退
//如果此时应用JTA事务失败,将仍会执行添加grade的事务并提交(前提是先于添加user操作)
//如果应用JTA事务成功,就会两个添加事务同时执行或同时回退。
user.setUser_id(1);
user.setUser_name("tufu");
user.setUser_password("tufu");
Grade grade = new Grade();
grade.setGrade(100);
grade.setUser(user);
ms.addGrade(user,grade);
}
}
注:将log4j.properties中的log4j日志设置为DEBUG级别,可以看到详细的JTA事务执行情况:
.......
log4j.rootLogger=DEBUG,R,A1
分享到:
相关推荐
Spring框架作为一个广泛使用的Java应用程序开发框架,提供了多种支持事务管理的解决方案,其中包括集成JOTM(Java Open Transaction Manager)来处理分布式事务。本文将深入探讨Spring与JOTM结合使用的知识点,帮助...
本文将详细介绍如何在Spring中使用JTA事务管理,包括通过集成JOTM(Java Open Transaction Manager)以及引用Tomcat的JTA事务。 ### 1. 通过集成JOTM,直接在Spring中使用JTA事务 #### 1.1. 添加JOTM类库到类路径...
本文将深入探讨如何在Tomcat应用服务器上集成JTA,并使用JOTM(Java Open Transaction Manager)或Atomikos作为事务管理器来实现分布式事务。 首先,我们需要理解JTA的核心概念。JTA是Java EE平台的一部分,提供了...
通过这样的配置和测试,我们可以验证Spring+iBatis+JOTM的JTA事务管理功能是否正常工作。这种方式特别适用于需要在非J2EE容器中实现分布式事务的场景,为应用提供了强大的事务管理能力。然而,需要注意的是,JTA事务...
对于分布式事务,Spring支持JTA事务管理,并且可以无缝集成JOTM。 1. **配置JOTM**:首先,你需要在项目的类路径下添加JOTM的依赖库。然后,在Spring的配置文件中定义JOTM的事务管理器 bean,例如: ```xml ...
JOTM 是一个开源的JTA事务管理器,实现了X/Open XA规范,允许跨多个资源进行分布式事务处理。它与各种数据库和JMS提供者兼容,为Java应用提供了强大的事务管理能力。JOTM可以在Spring框架中无缝集成,通过Spring的...
在Spring中集成JOTM可以提供更高级别的事务控制,确保在多数据源环境下事务的一致性和完整性。 首先,我们需要了解在没有使用JOTM时,Spring与Hibernate的常规配置。在提供的XML配置代码中,可以看到Spring配置了一...
在Spring中,可以通过集成JOTM来实现JTA的功能。JOTM是一个开源的Java事务管理器,符合X/Open XA规范,可以处理跨多个资源的事务。 要在Spring中配置JOTM,首先添加JOTM和Spring的JTA依赖到项目中。然后,定义一个`...
### Spring + JOTM 多数据源事务管理详解(三):JNDI + Tomcat 在本篇文章中,我们将深入探讨如何利用Spring框架结合JOTM(Java Open Transaction Manager)来实现多数据源下的分布式事务管理。我们将通过具体实例...
在Spring中,通过集成JOTM,可以实现全局的事务控制,确保在多资源操作中保持数据的一致性。 **集成步骤**: 1. **添加依赖**:首先,项目需要在构建配置(如pom.xml或build.gradle)中引入Spring 3.0.5和JOTM的...
在Spring中集成JOTM,可以利用其功能来管理跨数据库的事务。 JOTM相关的jar包包括`jotm-core.jar`,`xapool.jar`,`ow2-connector-1.5-spec.jar`和`ow2-jta-1.1-spec.jar`。这些库提供了JOTM的核心实现和连接池支持...
总的来说,这个示例项目是为了展示如何在Spring环境中集成Hibernate并利用JOTM进行复杂的事务管理,这对于开发大型、分布式的企业级应用尤其重要。理解并掌握这些技术的使用,有助于提升应用的健壮性和可维护性。
JOTM(Java Open Transaction Manager)是一个开源的事务管理器,它遵循JTA(Java Transaction API)标准,为Java应用程序提供全面的事务服务。这篇博客文章“使用JOTM实现分布式事务管理(多数据源)”将深入探讨如何...
本篇文章将探讨如何在Java环境中,利用Spring框架和Atomikos这样的第三方工具实现分布式事务管理,即JTA(Java Transaction API)的实践。 JTA是Java平台提供的一种标准API,用于管理跨越多个资源(如数据库、消息...
在实际应用中,JOTM 可能会与诸如 Spring 框架等进行整合,Spring 提供的事务管理抽象层使得与 JOTM 的集成变得更加简单。开发者可以利用 Spring 的 `@Transactional` 注解来自动管理事务的边界,提高代码的可读性...
通过这种方式,即使不在Java EE应用服务器环境中,Spring结合JOTM也能提供强大的JTA事务管理能力,确保跨数据库操作的一致性和可靠性。这极大地扩展了Spring的应用范围,使其成为轻量级和企业级应用的理想选择。
Spring集成JOTM(Java Open Transaction Manager)的JTA事务管理则提供了另一种选择,JOTM是一个开源的JTA事务管理器,适用于那些不希望使用Java EE服务器但又需要JTA功能的环境。 在Spring中使用JTA事务管理的文档...
这个DEMO可以帮助开发者理解如何在实际项目中集成JOTM和Spring进行分布式事务处理。需要注意的是,虽然DEMO中没有包含jar包,但你仍需自行获取并添加到项目中,否则无法正常运行。在实践中,根据具体的业务需求和...
此版本的JOTM jar 文件是用于集成到Java应用程序中,以提供事务管理服务的关键组件。 XAPool 是一个高效的连接池实现,通常用于JDBC连接管理。在JOTM中,XAPool jar 文件(xapool.jar)的作用是提供连接池服务,...