使用Spring+Hibernate+JOTM+Oracle9i集成解決方案的遭遇
Posted on 2006-08-11 18:03 Kerwin Weng 閱讀(7161) 評(píng)論(29) 編輯 收藏 所屬分類(lèi): Java EE
因?yàn)樵陧?xiàng)目中要用到多數(shù)據(jù)源,所以這次必須采用JTA這種分布式事務(wù)管理方案,后來(lái)決定選JOTM這個(gè)JTA的開(kāi)源實(shí)現(xiàn),網(wǎng)上關(guān)于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>
由于前期使用中的發(fā)現(xiàn)XAPool這個(gè)包里面有類(lèi)老是報(bào)連接方面的錯(cuò)誤,于是在參考了一篇網(wǎng)上的文章后把xapool和包裝連接的配置都去掉了,結(jié)果導(dǎo)致的是多數(shù)據(jù)源的事務(wù)根本無(wú)法實(shí)現(xiàn),后來(lái)仔細(xì)想想,覺(jué)得很詭異,xapool就是jotm實(shí)現(xiàn)多數(shù)據(jù)源事務(wù)的關(guān)鍵所在,怎么能不用?
于是仔細(xì)研究了下,發(fā)現(xiàn)很多問(wèn)題,首先,JOTM需要的依賴(lài)--CAROL包沒(méi)有JDK1.5的版本,需要自己下載源碼并編譯成新的ow_carol-all.jar
Xapool倒是有JDK1.5的版本xapool-1.5.0,但是跑起來(lái)老是報(bào)錯(cuò),于是去下了xapool的源文件,發(fā)現(xiàn)居然源碼都不能編譯通過(guò),還有JDK1.5的保留字在里面,真不知道作者是怎么發(fā)布出1.5.0的.于是自己改掉關(guān)鍵字,并修補(bǔ)了一些檢查不太嚴(yán)格的檢測(cè),并重新打了個(gè)版本.結(jié)果跑起來(lái)還是會(huì)報(bào)錯(cuò),不過(guò)是oracle報(bào)游標(biāo)用盡的錯(cuò)誤.
搜了一把就發(fā)現(xiàn)原來(lái)是Oracle9i有名的內(nèi)存溢出bug導(dǎo)致:Xapool對(duì)PreparedStatement進(jìn)行了Cache,同時(shí)Oracle有一個(gè)出名的內(nèi)存漏洞,PreparedStatement使用之后必須關(guān)閉,如果不關(guān)閉連續(xù)進(jìn)行SQL查詢(xún)會(huì)造成前面SQL的游標(biāo)不能釋放;
參考了網(wǎng)上的修改方案(xapool1.4的),又自己研究了半天,最后終于成功了,Xapool1.5的修改如下:
修改StandardConnectionPoolDataSource類(lèi)的public static final int DEFAULT_PREPAREDSTMTCACHESIZE = 0,(當(dāng)然也可以用配置的方式來(lái)注入)
這樣就關(guān)閉了PreparedStatement的Cache,而且也不會(huì)造成什么1.4中關(guān)閉連接時(shí)的異常等等.
最后根據(jù)實(shí)際情況,設(shè)置好dataSourceXXX這幾個(gè)bean的lifeTime,sleepTime,maxSize,checkLevelObject屬性(具體意義和設(shè)置方法可以參考網(wǎng)上的說(shuō)明)
就終于可以正式使用了,測(cè)試了下,情況還不錯(cuò):)
最近有很多朋友都說(shuō)他們配置不成功,可能是某些細(xì)節(jié)造成的吧,因?yàn)檫@套系統(tǒng)現(xiàn)在正在TCL總部順利的運(yùn)轉(zhuǎn)著,所有我相信這個(gè)方法還是可行的,如果大家有什么問(wèn)題需要我?guī)椭?我很樂(lè)意幫忙,有人說(shuō)要我自己改的xapool1.5,因?yàn)樵傥腋暮煤蟛痪?1.6就已經(jīng)發(fā)布了,所有我就沒(méi)有貼出來(lái)了,有問(wèn)題的朋友可以直接留言我你的msn,我會(huì)加你的.