- 浏览: 577170 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
a1641693970:
还不错,学习了
BeanUtils使用总结(二)LazyDynaBean -
zjfshowtime:
很好的办法,学习了。
ORA-28001: the password has expired -
ya654277yo:
哦,多谢分享
Apache整合Tomcat后get方式提交中文乱码问题解决 -
foolkeeper:
nice !!
jvm内存参数设定 -
tracy821:
谢谢了,找了好久才找到
关于Spring 声明式事务处理时,throws exception不回滚的问题
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,将其放到类路径下:
- #JNDI调用协议
- carol.protocols=jrmp
- #不使用CAROL JNDI封装器
- carol.start.jndi= false
- #不启动命名服务器
- carol.start.ns= false
3、在MYSQL中创建两个数据库 "jtatesta","jtatestb":
- 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、域对象、数据访问类和其他事务管理的一样,如:
- //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>注解驱动自动进行事务增强:
- 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 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方法:
- 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
.......
在特定应用服务器使用JTA
一般来说,Spring的事务抽象与应用服务器是无关的。不过,如果你如果希望事务管理器使用特定的UserTransaction 和
TransactionManager 对象(可以被自动探测),以获取更多的增强事务语义。这时,针对不同的Java
EE应用服务器,Spring的事务管理器可以采取不同的配置。 3 d0 W4 y5 k3 u, h! G
BEA WebLogic
在一个使用WebLogic 7.0、8.1或更高版本的环境中,你一般会优先选用特定于WebLogic的
WebLogicJtaTransactionManager 类来取代基础的 JtaTransactionManager
类,因为在WebLogic环境中,该类提供了对Spring事务定义的完全支持,超过了标准的JTA语义。你可以使用以下的配置达到目的:
<bean id="txManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"/> 7 n6 e" n' j: m9 X- Q
它的特性包括:支持事务名,支持为每个事务定义隔离级别,以及在任何环境下正确地恢复事务的能力。
IBM WebSphere
. |' v# o% K7 }( K& B
在WebSphere 5.1、5.0和4.x环境下,你可以使用Spring的
WebSphereTransactionManagerFactoryBean
类。这是一个工厂类,通过WebSphere的静态访问方法(每个版本的WebSphere中都不同)获取到JTA
TransactionManager 实例。一旦通过工厂bean获取到JTA TransactionManager
实例,就可以使用该实例装配一个Spring的 JtaTransactionManager bean,它封装了JTA
UserTransaction,提供增强的事务语义。你可以按以下方式进行配置: 8 |6 Y+ C: C: k6 C
①引用WebSphere的JTA事务管理器
< bean id = " wsJtaTm " class = " org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean " />
< bean id = " transactionManager " class = " org.springframework.transaction.jta.JtaTransactionManager " >
< property name = " transactionManager ref= " wsJtaTm " />
</
bean
>
小结
你既可以在没有任务应用服务器支持的情况下,直接通过集成JOTM在Spring中使用JTA事务管理,也可以通过引用Java
EE应用服务器的JNDI数据源,利用应用服务器提供的JTA事务功能间接实现Spring 中的JTA事务管理。为了利用一些高级Java
EE应用服务器的JTA事务高级功能,你可以通过Spring所提供的特定于应用服务器的JTA事务管理器进行配置。
发表评论
-
F5负载均衡WAS重定向端口问题
2014-05-27 11:09 3449基于F5 WAS负载均衡,可直接通过IP访问首页http:X ... -
Spring 多数据源声明式事务控制(PlatformTransactionManager )
2014-04-11 18:31 4722首先是TransactionManager的配置: ... -
Spring 动态数据源(AbstractRoutingDataSource )
2014-04-11 18:25 1662Spring动态配置多数据源,即在大型应用中对数据进行横向 ... -
(转)Spring Security 3.0 多页面登录配置
2012-10-19 17:01 5431网上很多文章是关于Spri ... -
同一个Weblogic两个Domain CookieName冲突导致session失效问题
2012-09-25 11:03 2912问题描述: 同一个weblogic下新 ... -
EL表达式在tomcat7.0下的new关键字不能使用
2012-08-24 17:25 4065最近生产系统部署个小应用,服务器选型tomcat7.0,一直运 ... -
设置WebLogic启动内存
2012-07-02 20:25 1516我们经常在使用WebLoigc部署应用程序后,发现程序运行速度 ... -
Tomcat处理HTTP请求源码分析(下)
2012-05-18 17:18 1379很多开源应用服务器都是集成tomcat作为web contai ... -
Tomcat处理HTTP请求源码分析(上)
2012-05-18 17:16 1182很多开源应用服务器都是集成tomcat作为web contai ... -
Tomcat配置集锦
2012-05-16 16:37 1024配置基础验证(Basic Authentication) 容 ... -
多Tomcat多JDK部署
2012-03-23 17:51 11271、bin/catalina.bat: echo Using ... -
linux下apache、tomcat的安装及优化
2012-02-29 11:48 4228本文主要内容: (1)安装apr,这是 Apache 为了提 ... -
在Tomcat中通过JOTM支持JTA
2011-12-27 19:40 2095Tomcat是Servlet容器,但它提供了JND ... -
jconsole监控JVM
2011-12-12 17:46 1565本地监控: Jconsole [processed] ... -
Spring 3.1整合EhCache
2011-08-29 16:42 1461Spring 3.1提供了对cache的 ... -
APACHE实现负载均衡
2011-08-09 12:58 1294随 着访问量的不断提高,以及对响应速度的要求,进行负载均衡设 ... -
理解session机制
2011-05-19 11:59 1417session机制是一种服务器端的机制,服务器使用一种类似于散 ... -
spring集成xfire教程
2011-04-02 15:20 1594配置web.xml <!-- SPRING ... -
(转)Tomcat5集群中的SESSION复制 (3)
2010-12-08 16:46 1028集群安装 为了 ... -
(转)Tomcat 5集群中的SESSION复制(2)
2010-12-08 16:45 1503Tomcat 5中的SESSION复制 ...
相关推荐
通过这样的配置和测试,我们可以验证Spring+iBatis+JOTM的JTA事务管理功能是否正常工作。这种方式特别适用于需要在非J2EE容器中实现分布式事务的场景,为应用提供了强大的事务管理能力。然而,需要注意的是,JTA事务...
3. **Spring配置**:在Spring的配置文件中,使用`jee:jta-data-source`或`jee:resource-ref`元素来引用之前创建的JNDI数据源,并配置`PlatformTransactionManager`为`org.objectweb.jotm.CurrentJOTM`。 **Atomikos...
对于分布式事务,Spring支持JTA事务管理,并且可以无缝集成JOTM。 1. **配置JOTM**:首先,你需要在项目的类路径下添加JOTM的依赖库。然后,在Spring的配置文件中定义JOTM的事务管理器 bean,例如: ```xml ...
要在Spring中配置JOTM,首先添加JOTM和Spring的JTA依赖到项目中。然后,定义一个`PlatformTransactionManager` bean,使用`JotmFactoryBean`来创建JOTM实例。这样,Spring就可以利用JOTM管理事务,确保在多数据源...
本文将详细介绍如何在Spring中使用JTA事务管理,包括通过集成JOTM(Java Open Transaction Manager)以及引用Tomcat的JTA事务。 ### 1. 通过集成JOTM,直接在Spring中使用JTA事务 #### 1.1. 添加JOTM类库到类路径...
JOTM可以在Spring框架中无缝集成,通过Spring的PlatformTransactionManager接口来配置和使用。 **Spring 配置JTA和JOTM** 在Spring中使用JTA和JOTM,首先需要在项目中引入JOTM的依赖。接着,你需要配置Spring的`...
在Spring中集成JOTM可以提供更高级别的事务控制,确保在多数据源环境下事务的一致性和完整性。 首先,我们需要了解在没有使用JOTM时,Spring与Hibernate的常规配置。在提供的XML配置代码中,可以看到Spring配置了一...
Spring框架作为一个广泛使用的Java应用程序开发框架,提供了多种支持事务管理的解决方案,其中包括集成JOTM(Java Open Transaction Manager)来处理分布式事务。本文将深入探讨Spring与JOTM结合使用的知识点,帮助...
在Spring中,通过集成JOTM,可以实现全局的事务控制,确保在多资源操作中保持数据的一致性。 **集成步骤**: 1. **添加依赖**:首先,项目需要在构建配置(如pom.xml或build.gradle)中引入Spring 3.0.5和JOTM的...
在Tomcat中配置JNDI资源,以便Spring可以使用这些数据源。具体的XML配置如下: ```xml auth="Container" factory="org.objectweb.jndi.DataSourceFactory" type="javax.sql.DataSource" driverClassName=...
而“jotm-2.0.10”则是JOTM的具体版本,包含其核心组件和必要的依赖,用于在Spring环境中配置和使用JOTM。 为了运行这个示例,你需要将这些jar包添加到你的项目类路径中,然后配置Spring的事务管理器为JOTM,并配置...
在Spring中集成JOTM,可以利用其功能来管理跨数据库的事务。 JOTM相关的jar包包括`jotm-core.jar`,`xapool.jar`,`ow2-connector-1.5-spec.jar`和`ow2-jta-1.1-spec.jar`。这些库提供了JOTM的核心实现和连接池支持...
此外,JOTM还支持与Spring框架的集成,可以轻松地在Spring应用上下文中配置和管理事务。通过使用`@Transactional`注解,开发者可以在方法级别声明事务,简化事务管理。 总之,JOTM是实现Java分布式事务管理的强大...
这个DEMO可以帮助开发者理解如何在实际项目中集成JOTM和Spring进行分布式事务处理。需要注意的是,虽然DEMO中没有包含jar包,但你仍需自行获取并添加到项目中,否则无法正常运行。在实践中,根据具体的业务需求和...
在实践过程中,首先需要在Spring配置文件中配置Atomikos事务管理器,包括设置事务超时时间、事务日志路径等参数。然后,为需要参与事务操作的数据源或消息队列注册为XAResources。接着,通过Spring的`@Transactional...
4. 使用Spring的事务注解或XML配置来指定哪些方法需要在JTA事务中执行。例如,假设有一个名为BbtForumImpl的类,其中的addTopic()方法需要在事务中运行,那么可以使用@Transactional注解标记这个方法,或者在Spring...
在实际应用中,JOTM 可能会与诸如 Spring 框架等进行整合,Spring 提供的事务管理抽象层使得与 JOTM 的集成变得更加简单。开发者可以利用 Spring 的 `@Transactional` 注解来自动管理事务的边界,提高代码的可读性...
在Spring中配置多个数据源并进行事务管理,可以参考以下步骤: 1. **配置数据源**:为每个数据库创建一个数据源Bean,例如`dataSource1`和`dataSource2`。这些数据源可以是基于JDBC的,也可以是其他ORM框架如...
在JOTM的场景中,Spring可以用来配置和管理事务边界,通过声明式事务管理,使得在应用代码中无需显式调用事务开始和结束,而是由Spring自动处理,提高了代码的可读性和可维护性。 将这些组件整合在一起,开发者可以...