论坛首页 Java企业应用论坛

jotm跨数据库事务 spring + hibernate

浏览 5911 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-04-26   最后修改:2011-05-04
jotm跨数据库 spring + hibernate


软件包
ow2-jotm-dist-2.1.9-bin.tar.gz
spring-framework-3.0.5.RELEASEhibernate-3.6.0.Final
hibernate-3.6.0.Final

spring和hibernate不再详述,讲讲jotm如何与spring集成
web开发中,使用hibernate的SessionFactory,而在SessionFactory中注入DataSource
DataSource需要支持事务,因此采用软件包ow2-jotm-dist-2.1.9-bin.tar.gz中的xapool.jar包来配置DataSource,放弃了org.springframework.jdbc.datasource.DriverManagerDataSource

配置jta事务管理器JtaTransactionManager
重点<property name="userTransaction" ref="jotm" />
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" />
	<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
		<property name="userTransaction" ref="jotm" />
		<property name="allowCustomIsolationLevels" value="true"></property>
	</bean>



数据源配置(DataSource)
重点<property name="transactionManager" ref="jotm" />
//1号数据库
<bean id="dataSource1" 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://127.0.0.1:3306/db1?characterEncoding=utf-8" />
            </bean>
        </property>
        <property name="user" value="root" />
        <property name="password" value="" />
    </bean>

//2号数据库
<bean id="dataSource2" 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://127.0.0.1:3306/db2?characterEncoding=utf-8" />
            </bean>
        </property>
        <property name="user" value="root" />
        <property name="password" value="" />
    </bean>


SessionFactory配置
重点<property name="dataSource" ref="dataSource1" />
重点<property name="dataSource" ref="dataSource2" />
//1号SessionFactory
<bean id="sessionFactory1" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	    <property name="hibernateProperties">
	    	<props>
	    		<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
	    	</props>
	    </property>
	   	<property name="dataSource" ref="dataSource1" />
		<property name="packagesToScan" value="com.yuce.test.entity"/>
	</bean>

//2号SessionFactory
<bean id="sessionFactory2" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	    <property name="hibernateProperties">
	    	<props>
	    		<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
	    	</props>
	    </property>
	   	<property name="dataSource" ref="dataSource2" />
		<property name="packagesToScan" value="com.yuce.test.entity"/>
	</bean>


附录
jotm必须的jar包
xapool.jar
jotm-core.jar
carol.jar
carol-interceptors.jar



后记:
在使用spring的    进行跨数据库测试的时候没有问题,而在发布web的时候,启动始终都报异常javax.resource.spi.XATerminator找不到,查看类库的时候发现该类就在javaee.jar中,但发布的时候始终找不到。后来发现,这是由于在MyEclipse发布web的时候,设置项目->属性->Order and Export中没有将javaee.jar等jar包发布到web中,于是勾选该jar包,但测试仍然不能成功。
最后将javaee.jar包copy到tomcat是lib目录中,启动tomcat进行测试,一切正常。
暂时好不知道为什么设置了Order and Export也不能行的原因,只是知道在MyEclipse在打包发布的时候也不是完全可信的。切记。
   发表时间:2011-08-03  
spring-framework-3.0.5.RELEASE 包中没有org.springframework.transaction.jta.JotmFactoryBean类,咋配啊?
0 请登录后投票
   发表时间:2011-08-03  
sky4160864 写道
spring-framework-3.0.5.RELEASE 包中没有org.springframework.transaction.jta.JotmFactoryBean类,咋配啊?



官方的回答是:
JOTM and XAPool support is dropped in Spring 3.0.x (it has been droppen on 28-november-2008 so for quite some time now). There is however no JIRA issue attached to the commit.
解决办法是:
1) Copy the code from 2.5.6 (JotmFactoryBean) to your own project and use that implementation
2) Simply instantiate your orn Jotm instance and use that instead of the factory bean
3) Use something else instead of Jotm
Either 3 will solve your problem.

推荐第一种解决办法:
自己写JotmFactoryBean,以下是spring2.5.6中的源码
/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction.jta;

import javax.naming.NamingException;
import javax.transaction.SystemException;

import org.objectweb.jotm.Current;
import org.objectweb.jotm.Jotm;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;

/**
 * {@link FactoryBean} that retrieves the JTA UserTransaction/TransactionManager
 * for ObjectWeb's <a href="http://jotm.objectweb.org">JOTM</a>. Will retrieve
 * an already active JOTM instance if found (e.g. if running in JOnAS),
 * else create a new local JOTM instance.
 *
 * <p>With JOTM, the same object implements both the
 * {@link javax.transaction.UserTransaction} and the
 * {@link javax.transaction.TransactionManager} interface,
 * as returned by this FactoryBean.
 *
 * <p>A local JOTM instance is well-suited for working in conjunction with
 * ObjectWeb's <a href="http://xapool.experlog.com">XAPool</a>, e.g. with bean
 * definitions like the following:
 *
 * <pre class="code">
 * &lt;bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/&gt;
 *
 * &lt;bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"&gt;
 *   &lt;property name="userTransaction" ref="jotm"/&gt;
 * &lt;/bean&gt;
 *
 * &lt;bean id="innerDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"&gt;
 *   &lt;property name="transactionManager" ref="jotm"/&gt;
 *   &lt;property name="driverName" value="..."/&gt;
 *   &lt;property name="url" value="..."/&gt;
 *   &lt;property name="user" value="..."/&gt;
 *   &lt;property name="password" value="..."/&gt;
 * &lt;/bean&gt;
 *
 * &lt;bean id="dataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"&gt;
 *   &lt;property name="dataSource" ref="innerDataSource"/&gt;
 *   &lt;property name="user" value="..."/&gt;
 *   &lt;property name="password" value="..."/&gt;
 *   &lt;property name="maxSize" value="..."/&gt;
 * &lt;/bean&gt;</pre>
 *
 * Note that Spring's {@link JtaTransactionManager} will automatically detect
 * that the passed-in UserTransaction reference also implements the
 * TransactionManager interface. Hence, it is not necessary to specify a
 * separate reference for JtaTransactionManager's "transactionManager" property.
 *
 * <p>Implementation note: This FactoryBean uses JOTM's static access method
 * to obtain the JOTM {@link org.objectweb.jotm.Current} object, which
 * implements both the UserTransaction and the TransactionManager interface,
 * as mentioned above.
 *
 * @author Juergen Hoeller
 * @since 21.01.2004
 * @see JtaTransactionManager#setUserTransaction
 * @see JtaTransactionManager#setTransactionManager
 * @see org.objectweb.jotm.Current
 */
public class JotmFactoryBean implements FactoryBean, DisposableBean {

	private Current jotmCurrent;

	private Jotm jotm;


	public JotmFactoryBean() throws NamingException {
		// Check for already active JOTM instance.
		this.jotmCurrent = Current.getCurrent();

		// If none found, create new local JOTM instance.
		if (this.jotmCurrent == null) {
			// Only for use within the current Spring context:
			// local, not bound to registry.
			this.jotm = new Jotm(true, false);
			this.jotmCurrent = Current.getCurrent();
		}
	}

	/**
	 * Set the default transaction timeout for the JOTM instance.
	 * <p>Should only be called for a local JOTM instance,
	 * not when accessing an existing (shared) JOTM instance.
	 */
	public void setDefaultTimeout(int defaultTimeout) {
		this.jotmCurrent.setDefaultTimeout(defaultTimeout);
		// The following is a JOTM oddity: should be used for demarcation transaction only,
		// but is required here in order to actually get rid of JOTM's default (60 seconds).
		try {
			this.jotmCurrent.setTransactionTimeout(defaultTimeout);
		}
		catch (SystemException ex) {
			// should never happen
		}
	}


	/**
	 * Return the JOTM instance created by this factory bean, if any.
	 * Will be <code>null</code> if an already active JOTM instance is used.
	 * <p>Application code should never need to access this.
	 */
	public Jotm getJotm() {
		return this.jotm;
	}

	public Object getObject() {
		return this.jotmCurrent;
	}

	public Class getObjectType() {
		return this.jotmCurrent.getClass();
	}

	public boolean isSingleton() {
		return true;
	}


	/**
	 * Stop the local JOTM instance, if created by this FactoryBean.
	 */
	public void destroy() {
		if (this.jotm != null) {
			this.jotm.stop();
		}
	}

}



也可以到http://s3.amazonaws.com/dist.springframework.org/release/SPR/spring-framework-2.5.6-with-dependencies.zip下载spring2.5.6,在源码里找到对应的类。
0 请登录后投票
   发表时间:2011-08-08  
我想知道的是 如果不用事物影响到底有多大。
0 请登录后投票
   发表时间:2011-08-27  
如果服务器使用tomcat,datasource使用jndi,那么jotm该如何配置?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics