两个不同网域的oracle数据库,处理之间的事务,
spring+hibernate+jotm组合,
一、环境及框架
Tomcat+spring+hibernate+jotm,struts,Oracle等
二、需求说明
系统里有2套不同网域的oracle数据库,之间的数据需要进行交互。
三、Dao配置
1、定义jtom Bean
- < bean id = "jotm" class = "org.springframework.transaction.jta.JotmFactoryBean" />
2、定义数据源
- < bean id = "dataSourceA" 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 local = "jotm" />
- </ property >
- < property name = "driverName" >
- < value > oracle.jdbc.driver.OracleDriver </ value >
- </ property >
- < property name = "url" >
- < value > jdbc:oracle:thin:@192.168.0.10:1521:A </ value >
- </ property >
- </ bean >
- </ property >
- < property name = "user" >
- < value > </ value >
- </ property >
- < property name = "password" >
- < value > </ value >
- </ property >
- </ bean >
- < bean id = "dataSourceB" 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 local = "jotm" />
- </ property >
- < property name = "driverName" >
- < value > oracle.jdbc.driver.OracleDriver </ value >
- </ property >
- < property name = "url" >
- < value > jdbc:oracle:thin:@192.168.0.10:1521:B </ value >
- </ property >
- </ bean >
- </ property >
- < property name = "user" >
- < value > </ value >
- </ property >
- < property name = "password" >
- < value > </ value >
- </ property >
- </ bean >
3、定义sessionFactory
xml 代码
- < bean id = "sessionFactoryA" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
- < property name = "dataSource" >
- < ref local = "dataSourceA" />
- </ property >
- < property name = "mappingDirectoryLocations" >
- < list >
- < value > classpath:/org/testa/hibernate/model/ </ value >
- </ list >
- </ property >
- < property name = "hibernateProperties" >
- < props >
- < prop key = "hibernate.dialect" > org.hibernate.dialect.Oracle9Dialect </ prop >
- < prop key = "hibernate.show_sql" > true </ prop >
- < prop key = "hibernate.jdbc.batch_size" > 50 </ prop >
- < prop key = "hibernate.cache.use_query_cache" > true </ prop >
- < prop key = "hibernate.cache.provider_class" > org.hibernate.cache.EhCacheProvider </ prop >
- </ props >
- </ property >
- < property name = "jtaTransactionManager" >
- < ref bean = "jotm" />
- </ property >
- < property name = "lobHandler" ref = "lobHandler" />
- </ bean >
- < bean id = "sessionFactoryB" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
- < property name = "dataSource" >
- < ref local = "dataSourceB" />
- </ property >
- < property name = "mappingDirectoryLocations" >
- < list >
- < value > classpath:/org/testb/hibernate/model/ </ value >
- </ list >
- </ property >
- < property name = "hibernateProperties" >
- < props >
- < prop key = "hibernate.dialect" > org.hibernate.dialect.Oracle9Dialect </ prop >
- < prop key = "hibernate.show_sql" > true </ prop >
- < prop key = "hibernate.jdbc.batch_size" > 50 </ prop >
- < prop key = "hibernate.cache.use_query_cache" > true </ prop >
- < prop key = "hibernate.cache.provider_class" > org.hibernate.cache.EhCacheProvider </ prop >
- </ props >
- </ property >
- < property name = "jtaTransactionManager" >
- < ref bean = "jotm" />
- </ property >
- < property name = "lobHandler" ref = "lobHandler" />
- </ bean >
4、事务管理配置
xml 代码
- < bean id = "myTransactionManager"
- class = "org.springframework.transaction.jta.JtaTransactionManager" >
- < property name = "userTransaction" >
- < ref local = "jotm" />
- </ property >
- </ bean >
5、dao的配置
xml 代码
- < bean id = "testADaoTarget" class = "org.testa.hibernate.dao.impl.TestADAO" >
- < property name = "sessionFactory" >
- < ref bean = " sessionFactoryA " />
- </ property >
- </ bean >
- < bean id = "testADao" class = "org.springframework.aop.framework.ProxyFactoryBean" >
- < property name = "proxyInterfaces" >
- < value > org.testA.hibernate.dao.ITestADAO </ value >
- </ property >
- < property name = "interceptorNames" >
- < list >
- < value > testADaoTarget </ value >
- </ list >
- </ property >
- </ bean >
- < bean id = "testBDaoTarget" class = "org.testa.hibernate.dao.impl.TestBDAO" >
- < property name = "sessionFactory" >
- < ref bean = " sessionFactoryB " />
- </ property >
- </ bean >
- < bean id = "testBDao" class = "org.springframework.aop.framework.ProxyFactoryBean" >
- < property name = "proxyInterfaces" >
- < value > org.testA.hibernate.dao.ITestBDAO </ value >
- </ property >
- < property name = "interceptorNames" >
- < list >
- < value > testBDaoTarget </ value >
- </ list >
- </ property >
- </ bean >
四、注意事项
1、spring已经整合了jotm,如果你使用spring自带的jotm,可能会提示某些类找不到,下载一个最新的jotm包,把lib目录里的所有jar包拷贝到lib目录。
2、如果系统中使用jndi,则原有的jndi服务可能会无效,提示NameNotFoundException异常,此时在src目录下添加一个carol.properties的属性文件,添加如下内容:
xml 代码
- # do not use CAROL JNDI wrapper
- carol.start.jndi = false
- # do not start a name server
- carol.start.ns = false
- # Naming Factory
- carol.jndi.java.naming.factory.url.pkgs = org .apache.naming
觉得这个地方有点问题啊
<bean id="testADao" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.testA.hibernate.dao.ITestADAO</value>
</property>
<property name="interceptorNames">
<list>
<value> testADaoTarget </value>
</list>
</property>
</bean>
<property name="interceptorNames">里面应该是截取器列表,testADaoTarget应放在target属性吧
这里的dao只是个代理而已,如你所说,它的执行者最后是testADaoTarget
我的想法是,既然是分布式事务,不应该在dao层进行事务拦截,而应该提升到service层。
上面我把service层省略了,比如我这么写:
- <bean id= "myTransactionManager"
- class = "org.springframework.transaction.jta.JtaTransactionManager" >
- <property name="userTransaction" >
- <ref local="jotm" />
- </property>
- </bean>
<bean id="myTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction">
<ref local="jotm" />
</property>
</bean>
- <bean id= "transactionInterceptor" class = "org.springframework.transaction.interceptor.TransactionInterceptor" >
- <property name="transactionManager" >
- <ref bean="myTransactionManager" />
- </property>
- </bean>
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="myTransactionManager"/>
</property>
</bean>
然后你在自己的service层的拦截器列表中添加这个transactionInterceptor拦截器就可以了,由它里边的jtom管理事务。
如:
- <bean id= "testManagerTarget" class = "org.test.spring.service.impl.testServiceImpl" >
- <property name="testADao" >
- <ref bean="testADao" />
- </property>
- <property name="testBDao" >
- <ref bean="testBDao" />
- </property>
- </bean>
<bean id="testManagerTarget" class="org.test.spring.service.impl.testServiceImpl">
<property name="testADao">
<ref bean="testADao"/>
</property>
<property name="testBDao">
<ref bean="testBDao"/>
</property>
</bean>
- <bean id= "testService" class = "org.springframework.aop.framework.ProxyFactoryBean" >
- <property name="proxyInterfaces" >
- <value>org.test.spring.service.ItestService</value>
- </property>
- <property name="interceptorNames" >
- <list>
- <idref bean="transactionInterceptor" />
- </list>
- </property>
- </bean>