`

用Spring集成的JOTM配置分布式事务,结合hibernate jpa

 
阅读更多
最近项目中涉及到了两个Oracle数据库的操作。需要用到分布式事务,研究之后贴出代码供大家参考。

1.dao-core.xml(核心事务配置XML)
<?xml version="1.0" encoding="UTF-8"?>
<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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 支持注解 -->
    <context:annotation-config />
    <bean id="jotm"
          class="org.springframework.transaction.jta.JotmFactoryBean" />
    <bean id="txManager"
          class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="userTransaction" ref="jotm" />
    </bean>
    <!--两个数据源-->
    <bean id="cmcDataSource" 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="oracle.jdbc.driver.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@192.168.6.80:1521:C2SServer"/>
                <property name="user" value="d1xn_cmc"/>
                <property name="password" value="d1xn_cmc"/>
            </bean>
        </property>
        <property name="user" value="d1xn_cmc"/>
        <property name="password" value="d1xn_cmc"/>
    </bean>
    <bean id="woniuDataSource" 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="oracle.jdbc.driver.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@192.168.6.80:1521:C2SServer"/>
                <property name="user" value="sn_woniu"/>
                <property name="password" value="sn_woniu"/>
            </bean>
        </property>
        <property name="user" value="sn_woniu"/>
        <property name="password" value="sn_woniu"/>
    </bean>
    <!-- =================== 事务管理AOP配置 =================== -->
    <bean id="cmcEntityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:com/d1xn/commercial/dao/config/persistence.xml"/>
        <property name="persistenceUnitName" value="CMC_PU"/>
        <property name="dataSource" ref="cmcDataSource"/>
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
        </property>
        <property name="jpaPropertyMap">
            <map>
                <entry key="hibernate.transaction.manager_lookup_class"
                       value="org.hibernate.transaction.JOTMTransactionManagerLookup" />
                <entry key="hibernate.transaction.flush_before_completion" value="true" />
                <entry key="hibernate.transaction.auto_close_session" value="true" />
                <entry key="hibernate.current_session_context_class" value="jta" />
                <entry key="hibernate.connection.release_mode" value="auto" />
            </map>
        </property>
    </bean>
    <bean id="woniuEntityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:com/d1xn/commercial/dao/config/persistenceWoniu.xml"/>
        <property name="persistenceUnitName" value="WONIU_PU"/>
        <property name="dataSource" ref="woniuDataSource"/>
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
        </property>
        <property name="jpaPropertyMap">
            <map>
                <entry key="hibernate.transaction.manager_lookup_class"
                       value="org.hibernate.transaction.JOTMTransactionManagerLookup" />
                <entry key="hibernate.transaction.flush_before_completion" value="true" />
                <entry key="hibernate.transaction.auto_close_session" value="true" />
                <entry key="hibernate.current_session_context_class" value="jta" />
                <entry key="hibernate.connection.release_mode" value="auto" />
            </map>
        </property>
    </bean>
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="save*" rollback-for="Excepiton"/>
            <tx:method name="delete*" rollback-for="Excepiton"/>
            <tx:method name="update*" rollback-for="Excepiton"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*" rollback-for="java.lang.Exception"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="userOperation"
                      expression="execution(public  * com.d1xn.commercial.dao.imp.*Service*.*(..))"/>
        <aop:advisor advice-ref="txAdvice"
                     pointcut-ref="userOperation"/>
    </aop:config>
    <!-- ===================== AOP事务配置结束 ====================== -->
    <!-- 业务类 -->
    <bean id="cmcDaoHelper" class="com.d1xn.dao.core.DAOHelper" init-method="init">
        <property name="entityManagerHelper">
            <bean class="com.d1xn.commercial.dao.cmc.CmcEntityManagerHelper"/>
        </property>
    </bean>
    <bean id="woniuDaoHelper" class="com.d1xn.dao.core.DAOHelper" init-method="init">
        <property name="entityManagerHelper">
            <bean class="com.woniu.system.dao.WoniuEntityManagerHelper"/>
        </property>
    </bean>
    <bean id="jtaTestService" class="com.d1xn.commercial.dao.imp.JTATestService">
        <property name="cmcDaoHelper" ref="cmcDaoHelper"/>
        <property name="woniuDaoHelper" ref="woniuDaoHelper"/>
    </bean>
</beans>


2.persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">
    <persistence-unit name="CMC_PU" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>com.d1xn.commercial.pojo.cmc.entity.GameGoodsType</class>
        <class>com.d1xn.commercial.pojo.cmc.entity.ThreeRole</class>
        <properties>
           <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9Dialect" />
			<property name="hibernate.show_sql" value="true" />
			<!-- 最大连接数 -->
			<property name="hibernate.c3p0.max_size" value="20"/>
			<!-- 最小连接数 -->
			<property name="hibernate.c3p0.min_size" value="5"/>
			<!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 -->
			<property name="hibernate.c3p0.timeout" value="120"/>
			<!-- 最大的PreparedStatement的数量 -->
			<property name="hibernate.c3p0.max_statements" value="100"/>
			<!-- 每隔120秒检查连接池里的空闲连接 ,单位是秒-->
			<property name="hibernate.c3p0.idle_test_period" value="120"/>
			<!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 -->
			<property name="hibernate.c3p0.acquire_increment" value="2"/>
			<!-- 每次都验证连接是否可用 -->
			<property name="hibernate.c3p0.validate" value="true"/>
        </properties>
    </persistence-unit>
</persistence>


3.persistenceWoniu.xml


<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">
    <persistence-unit name="WONIU_PU" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>com.woniu.system.pojo.SysCompany</class>
        <class>com.woniu.system.pojo.SysUserRole</class>
        <class>com.woniu.system.pojo.SysUserRoleId</class>
        <properties>
           <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9Dialect" />
			<property name="hibernate.show_sql" value="true" />
			<!-- 最大连接数 -->
			<property name="hibernate.c3p0.max_size" value="20"/>
			<!-- 最小连接数 -->
			<property name="hibernate.c3p0.min_size" value="5"/>
			<!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 -->
			<property name="hibernate.c3p0.timeout" value="120"/>
			<!-- 最大的PreparedStatement的数量 -->
			<property name="hibernate.c3p0.max_statements" value="100"/>
			<!-- 每隔120秒检查连接池里的空闲连接 ,单位是秒-->
			<property name="hibernate.c3p0.idle_test_period" value="120"/>
			<!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 -->
			<property name="hibernate.c3p0.acquire_increment" value="2"/>
			<!-- 每次都验证连接是否可用 -->
			<property name="hibernate.c3p0.validate" value="true"/>
        </properties>
    </persistence-unit>
</persistence>


4.MyTest-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
     
      <import resource="classpath:com/d1xn/commercial/dao/config/dao-core.xml"/>
    
</beans>


5.IJTATestService.java接口

public interface IJTATestService {
	public boolean saveEntity(IEntity woniu, IEntity cmc);
}


6.JTATestService.java类

public class JTATestService implements IJTATestService {
    private DAOHelper woniuDaoHelper;
    private DAOHelper cmcDaoHelper;
    public boolean saveEntity(IEntity woniu, IEntity cmc) {
         woniuDaoHelper.persist(woniu);
        cmcDaoHelper.persist(cmc);
        return false;
    }
    public void setWoniuDaoHelper(DAOHelper woniuDaoHelper) {
        this.woniuDaoHelper = woniuDaoHelper;
    }
    public void setCmcDaoHelper(DAOHelper cmcDaoHelper) {
        this.cmcDaoHelper = cmcDaoHelper;
    }
}


7. MyTest.java


@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {
    @Autowired
	private IJTATestService service;
    @org.junit.Test
    public void test() {
        SysCompany sysCompany = new SysCompany();
        sysCompany.setSName("sss");
        sysCompany.setSState("0");
        SysUserRole role = new SysUserRole();
        SysUserRoleId id = new SysUserRoleId();
        id.setNRoleId(2L);
        id.setNUserId(1L);
        role.setId(id);
        GameGoodsType type = new GameGoodsType();
        type.setSNo("aaa");
        type.setSName("222");
        type.setSState("1");
        service.saveEntity(sysCompany, type);
    }
}


8.通过EntityManagerFactory得到sessionFactory

EntityManager entityManager=this.getCmsEntityManagerFactory().createEntityManager();
Session session=(Session)entityManager.getDelegate();
SessionFactory sessionFactory=session.getSessionFactory();


9.特别说明

在项目测试的过程中,有一个错误困扰了我很久,总会报这样的错误

Hibernate: select SN_WONIU.SYS_COMPANY_SQ.nextval from dual
java.sql.SQLException: Cannot get connection for URL jdbc:oracle:thin:@192.168.6.80:1521:C2SServer : 调用中无效的参数

Google了一大圈有不少人碰到这个问题,后来偶是在http://forum.springsource.org/archive/index.php/t-28145.html找到了答案,就是在配置数据源的时候,StandardXAPoolDataSource中要配置user和password,StandardXADataSource中也要配置user和password。 不明白为啥,希望高人不吝赐教。

分享到:
评论

相关推荐

    Spring+JOTM 分布式事务管理

    本文将深入探讨Spring与JOTM结合使用的知识点,帮助你理解如何在实际项目中实施分布式事务。 **1. Spring事务管理:** Spring 提供了声明式和编程式的事务管理。声明式事务管理是通过在配置文件或注解中声明事务...

    spring + JTA + JOTM实现分布式事务

    接下来,我们将结合Spring框架来讨论如何配置和使用JTA和JOTM。Spring是一个强大的企业级应用开发框架,它提供了一整套事务管理解决方案,包括编程式和声明式事务管理。对于分布式事务,Spring支持JTA事务管理,并且...

    spring JTA集成JOTM或Atomikos配置分布式事务(Tomcat应用服务器)

    本文将深入探讨如何在Tomcat应用服务器上集成JTA,并使用JOTM(Java Open Transaction Manager)或Atomikos作为事务管理器来实现分布式事务。 首先,我们需要理解JTA的核心概念。JTA是Java EE平台的一部分,提供了...

    spring+jotm+ibatis+mysql实现JTA分布式事务

    总的来说,这个项目展示了如何利用Spring的事务管理能力,结合JOTM作为事务协调器,以及iBATIS作为数据访问层,实现基于MySQL的JTA分布式事务处理。这不仅有助于理解分布式事务的原理,也为实际开发提供了可参考的...

    使用JOTM实现分布式事务管理(多数据源)

    此外,JOTM还支持与Spring框架的集成,可以轻松地在Spring应用上下文中配置和管理事务。通过使用`@Transactional`注解,开发者可以在方法级别声明事务,简化事务管理。 总之,JOTM是实现Java分布式事务管理的强大...

    Spring+Jotm+Hibernate+Oracle+Junit 实现JTA分布式事务要求Demo工程

    2.Spring+Jotm整合实现JTA分布式事务,应用场景如转账等,同一事务内完成db1用户加100元、db2用户减100元。 3.Spring+Junit4单元测试,优点:不会破坏数据库现场,等等。 (特别注意:Spring3.0里不在提供对jotm的...

    spring+jotm 多数据源事务管理(二)hibernate

    本篇文章将聚焦于如何结合Spring和JOTM(Java Open Transaction Manager)来实现多数据源的事务管理,特别是针对使用Hibernate的情况。 JOTM是Java平台上的一个开放源代码事务管理器,它遵循JTA(Java Transaction ...

    Spring分布式事务实现

    在Spring中集成JOTM,可以利用其功能来管理跨数据库的事务。 JOTM相关的jar包包括`jotm-core.jar`,`xapool.jar`,`ow2-connector-1.5-spec.jar`和`ow2-jta-1.1-spec.jar`。这些库提供了JOTM的核心实现和连接池支持...

    Java分布式开发spring+jta+jotm

    JOTM可以在Spring框架中无缝集成,通过Spring的PlatformTransactionManager接口来配置和使用。 **Spring 配置JTA和JOTM** 在Spring中使用JTA和JOTM,首先需要在项目中引入JOTM的依赖。接着,你需要配置Spring的`...

    spring-hibernate-jotm 例子

    总的来说,这个示例项目是为了展示如何在Spring环境中集成Hibernate并利用JOTM进行复杂的事务管理,这对于开发大型、分布式的企业级应用尤其重要。理解并掌握这些技术的使用,有助于提升应用的健壮性和可维护性。

    jta分布式事务完成例子,测试通过

    例子虽小,可覆盖面广,设计spring载入.properties文件,spring配置jta和jotm分布式事务,设置数据源连接池,注解事务驱动。功能是在mysql上建立了两个数据库分别为dbone和dbtwo,在dbone里有表tb1,表中只有一个字段...

    spring+jotm 多数据源事务管理(三)JNDI+Tomcat

    本文详细介绍了如何在Tomcat服务器环境下使用Spring框架结合JOTM进行多数据源下的分布式事务管理。通过上述步骤,开发者可以轻松地搭建起一套完整的多数据源事务处理环境,为复杂业务场景提供强大的支持。这种配置...

    Spring+iBatis+JOTM实现JTA事务

    在集成Spring+iBatis+JOTM的环境中,Spring主要负责事务策略的配置和管理,iBatis则作为持久层框架,负责SQL的执行,而JOTM作为事务管理器,确保跨数据库的事务一致性。 1. **环境搭建** - 首先,确保安装了JDK ...

    多数据源 更新 spring jta java jotm

    通过Spring的`AbstractRoutingDataSource`和JTA,我们可以轻松地管理多个数据源,并通过JOTM保证分布式事务的一致性。在实际项目中,这种架构可以帮助我们构建可扩展、高可用的系统。在SpringDemo项目中,你可以找到...

    spring 3.0.5 + jotm 实现的的spring mvc 的例子

    标题中的“spring 3.0.5 + jotm 实现的的spring mvc 的例子”表明这是一个关于使用Spring 3.0.5版本与JOTM(Java Open Transaction Manager)结合构建Spring MVC应用的示例项目。这个项目可能旨在演示如何在Spring ...

    JOTM简单测试DEMO(不含jar包)

    本DEMO主要展示了如何在Spring框架中结合JOTM来处理分布式事务,特别是涉及多个数据源的情况。 首先,我们需要理解JOTM的基本概念。JOTM作为一个事务协调者,负责管理跨多个资源的事务,确保它们要么全部成功,要么...

    JOTM 分布式事务初探(JNDI,Tomcat 7 JDBC Pool连接池)

    NULL 博文链接:https://jackyin5918.iteye.com/blog/1922379

Global site tag (gtag.js) - Google Analytics