因為在項目中要用到多數據源,所以這次必須采用JTA這種分布式事務管理方案,后來決定選JOTM這個JTA的開源實現,網上關于JOTM的文章很多了,就不贅述了,貼下我的配置吧(carol.properties就免了吧):
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>
<!--JOTM-->
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction">
<ref local="jotm"/>
</property>
</bean>
<bean id="abstractTransactionProxy" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
</property>
</bean>
<bean id="abstractTmsSessionProxy" abstract="true">
<property name="sessionFactory" ref="tmsSessionFactory"/>
</bean>
<bean id="abstractWmsSessionProxy" abstract="true">
<property name="sessionFactory" ref="wmsSessionFactory"/>
</bean>
<bean id="abstractFmsSessionProxy" abstract="true">
<property name="sessionFactory" ref="fmsSessionFactory"/>
</bean>
<!-- WMS data source -->
<bean id="innerDataSourceWms" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="driverName">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@10.4.1.110:1521:testdb</value>
</property>
<property name="user">
<value>t_wms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="dataSourceWms" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
<property name="dataSource">
<ref local="innerDataSourceWms"/>
</property>
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="maxSize">
<value>10</value>
</property>
<property name="user">
<value>t_wms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="wmsSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceWms"/>
<property name="lobHandler" ref="lobHandler"/>
<property name="mappingResources">
<list>
........
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="jtaTransactionManager">
<ref bean="jotm"/>
</property>
</bean>
<!--TMS data source-->
<bean id="innerDataSourceTms" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="driverName">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@10.4.1.110:1521:testdb</value>
</property>
<property name="user">
<value>t_tms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="dataSourceTms" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
<property name="dataSource">
<ref local="innerDataSourceTms"/>
</property>
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="maxSize">
<value>10</value>
</property>
<property name="user">
<value>t_tms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="tmsSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceTms"/>
<property name="lobHandler" ref="lobHandler"/>
<property name="mappingResources">
<list>
....
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="jtaTransactionManager">
<ref bean="jotm"/>
</property>
</bean>
<!--FMS data source-->
<bean id="innerDataSourceFms" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="driverName">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@10.4.1.110:1521:testdb</value>
</property>
<property name="user">
<value>t_fms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="dataSourceFms" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
<property name="dataSource">
<ref local="innerDataSourceFms"/>
</property>
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="maxSize">
<value>10</value>
</property>
<property name="user">
<value>t_fms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="fmsSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceFms"/>
<property name="lobHandler" ref="lobHandler"/>
<property name="mappingResources">
<list>
.....
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="jtaTransactionManager">
<ref bean="jotm"/>
</property>
</bean>
由于前期使用中的發現XAPool這個包里面有類老是報連接方面的錯誤,于是在參考了一篇網上的文章后把xapool和包裝連接的配置都去掉了,結果導致的是多數據源的事務根本無法實現,后來仔細想想,覺得很詭異,xapool就是jotm實現多數據源事務的關鍵所在,怎么能不用?
于是仔細研究了下,發現很多問題,首先,JOTM需要的依賴--CAROL包沒有JDK1.5的版本,需要自己下載源碼并編譯成新的ow_carol-all.jar
Xapool倒是有JDK1.5的版本xapool-1.5.0,但是跑起來老是報錯,于是去下了xapool的源文件,發現居然源碼都不能編譯通過,還有JDK1.5的保留字在里面,真不知道作者是怎么發布出1.5.0的.于是自己改掉關鍵字,并修補了一些檢查不太嚴格的檢測,并重新打了個版本.結果跑起來還是會報錯,不過是oracle報游標用盡的錯誤.
搜了一把就發現原來是Oracle9i有名的內存溢出bug導致:Xapool對PreparedStatement進行了Cache,同時Oracle有一個出名的內存漏洞,PreparedStatement使用之后必須關閉,如果不關閉連續進行SQL查詢會造成前面SQL的游標不能釋放;
參考了網上的修改方案(xapool1.4的),又自己研究了半天,最后終于成功了,Xapool1.5的修改如下:
修改StandardConnectionPoolDataSource類的public static final int DEFAULT_PREPAREDSTMTCACHESIZE = 0,(當然也可以用配置的方式來注入)
這樣就關閉了PreparedStatement的Cache,而且也不會造成什么1.4中關閉連接時的異常等等.
最后根據實際情況,設置好dataSourceXXX這幾個bean的lifeTime,sleepTime,maxSize,checkLevelObject屬性(具體意義和設置方法可以參考網上的說明)
就終于可以正式使用了,測試了下,情況還不錯:)
最近有很多朋友都說他們配置不成功,可能是某些細節造成的吧,因為這套系統現在正在TCL總部順利的運轉著,所有我相信這個方法還是可行的,如果大家有什么問題需要我幫助,我很樂意幫忙,有人說要我自己改的xapool1.5,因為再我改好后不久,1.6就已經發布了,所有我就沒有貼出來了,有問題的朋友可以直接留言我你的msn,我會加你的.