spring3.0.3+hibernate3.5.4+JOTM2.2.1实现JTA事务管理

本文参考资料:http://java.e800.com.cn/articles/2007/417/1176746498587392322_1.html

 

实验方法:本文设置两个entity(Topic对应test1数据库, Post对应test2数据库 ),在事务处理中,如果不抛异常,就分别往Topic与Post所对应数据库的表添加一条记录;如果抛异常,则两个数据库的表不添加记录。

 

注:spring3.0.3关于事务的jar包中去掉了原来有的JotmFactoryBean.class,我从2.5.5版本中拷贝到3.0.3中使用。

 

Topic的类定义以下映射文件如下:

 

package entity;
public class Topic {

    private long oid;
    private String name;
    private int flat;


    public long getOid() {return oid;}
    public void setOid(long oid) {this.oid = oid;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getFlat() {return flat;}
    public void setFlat(int flat) {this.flat = flat;}
}

 

<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
    <class name="Topic" table="TOPIC">
           <id name="oid" column="oid" type="long">
               <generator class="native"/>
          </id>
          <property name="name"/>
          <property name="flat"/>
      </class>
 </hibernate-mapping>

 

Post的类定义以下映射文件如下:

 

package entity;


public class Post {

    private long oid;
    private String name;
    private int flat;


    public long getOid() {return oid;}
    public void setOid(long oid) {this.oid = oid;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getFlat() {return flat;}
    public void setFlat(int flat) {this.flat = flat;}
}

 

<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
    <class name="Post" table="POST">
           <id name="oid" column="oid" type="long">
               <generator class="native"/>
          </id>
          <property name="name"/>
          <property name="flat"/>
      </class>
 </hibernate-mapping>

 

在Spring配置文件中配置JOTM

 

<!-- JOTM本地实例 -->
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" />

<!-- JTA事务管理器 -->
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <!-- 指定userTransaction属性 -->
    <property name="userTransaction" ref="jotm" />
</bean>


<!-- 业务类中的@Transaction注解进行驱动 -->
<tx:annotation-driven transaction-manager="txManager" />


<!-- XAPool配置,内部包含了一个XA数据源,对应test1数据库 -->
<bean id="topicDS" 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:3306/test1?characterEncoding=gbk" />
        </bean>
    </property>
    <property name="user" value="yangyongbin" />
    <property name="password" value="bensun" />
</bean>
<!-- XAPool配置,内部包含了一个XA数据源,对应test2数据库 -->
<bean id="postDS" 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:3306/test2?characterEncoding=gbk" />
        </bean>
    </property>
    <property name="user" value="yangyongbin" />
    <property name="password" value="bensun" />
</bean>

 

spring关于hibernate的设置

<bean id="topicSessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
   <ref bean="topicDS" />
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">
     org.hibernate.dialect.MySQLInnoDBDialect
    </prop>
    <prop key="hibernate.hbm2ddl.auto">create</prop>
    <prop key="hibernate.show_sql">true</prop>
   </props>
  </property>
 <property name="mappingResources">
   <list>
    <value>entity/topic.hbm.xml</value></list>
  </property>
 </bean>
 
 <bean id="postSessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
   <ref bean="postDS" />
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">
     org.hibernate.dialect.MySQLInnoDBDialect
    </prop>
    <prop key="hibernate.hbm2ddl.auto">create</prop>
    <prop key="hibernate.show_sql">true</prop>
   </props>
  </property>
 <property name="mappingResources">
   <list>
    <value>entity/post.hbm.xml</value></list>
  </property>
 </bean>

Topic和Post的业务类(它们不实现接口。BbsServiceImpl实现了接口,并调用Topic与Post业务类添加记录)
<bean id="topicService" class="service.TopicServiceImpl">
    <property name="sessionFactory">
        <ref bean="topicSessionFactory"/>
    </property>
</bean>
<bean id="postService" class="service.PostServiceImpl">
    <property name="sessionFactory">
        <ref bean="postSessionFactory"/>
    </property>
</bean>

<!-- 进行跨数据库JTA事务的业务类 -->
<bean id="bbsService" class="service.BbsServiceImpl">
<property name="topicService" ref="topicService" />
<property name="postService" ref="postService" />
</bean>

 

TopicServiceImpl 与 PostServiceImpl定义

 

package service;


import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import entity.Topic;


public class TopicServiceImpl extends HibernateDaoSupport {
    public void save(Topic topic){
        this.getHibernateTemplate().saveOrUpdate(topic);
    }
}

 

package service;


import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import entity.Post;


public class PostServiceImpl extends HibernateDaoSupport{
    public void save(Post post){
        this.getHibernateTemplate().saveOrUpdate(post);
    }
}

 

BbsService 与 BbsServiceImpl 定义

 

package service;


public interface BbsService {
    public void add();
}

 

package service;


import org.springframework.transaction.annotation.Transactional;
import entity.Post;
import entity.Topic;


@Transactional //事务注解,以便Spring动态织入事务管理功能
public class BbsServiceImpl implements BbsService {
    private TopicServiceImpl topicService;
    private PostServiceImpl postService;

    public void setTopicService(TopicServiceImpl topicService) {
        this.topicService = topicService;
    }
    public void setPostService(PostServiceImpl postService) {
        this.postService = postService;
    }
    @Override
    public void add() {//该方法将被施加JTA事务的增强
  
        Topic topic=new Topic();
        topic.setName("第一Topic");
        topic.setFlat(1);
       
        Post post=new Post();
        post.setName("第一Post");
        post.setFlat(0);
       
        topicService.save(topic);
        postService.save(post);
       
        throw new RuntimeException("事务回滚!");
    }

}


测试类定义

package test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import service.BbsService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:/applicationContext_jotm.xml") 
public class UTest_JOTM {

    @Autowired 
    private BbsService bbsService; 
   
    @Test
    public void test(){
        bbsService.add();
    }
     
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值