使用Spring+Hibernate+JOTM+Oracle9i集成解决方案的遭遇

本文详细介绍了如何使用JOTM实现多数据源的分布式事务管理,并解决了XAPool连接池出现的问题,包括Oracle内存溢出Bug的解决办法。

转载自: http://www.blogjava.net/hunteva/archive/2009/01/20/62936.html


因为在项目中要用到多数据源,所以这次必须采用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,我会加你的.


下载前必看:https://pan.quark.cn/s/a4b39357ea24 在本资料中,将阐述如何运用JavaScript达成单击下拉列表框选定选项后即时转向对应页面的功能。 此种技术适用于网页布局中用户需迅速选取并转向不同页面的情形,诸如网站导航栏或内容目录等场景。 达成此功能,能够显著改善用户交互体验,精简用户的操作流程。 我们须熟悉HTML里的`<select>`组件,该组件用于构建一个选择列表。 用户可从中选定一项,并可引发一个事件来响应用户的这一选择动作。 在本次实例中,我们借助`onchange`事件监听器来实现当用户在下拉列表框中选定某个选项时,页面能自动转向该选项关联的链接地址。 JavaScript里的`window.location`属性旨在获取或设定浏览器当前载入页面的网址,通过变更该属性的值,能够实现页面的转向。 在本次实例的实现方案里,运用了`eval()`函数来动态执行字符串表达式,这在现代的JavaScript开发实践中通常不被推荐使用,因为它可能诱发安全问题及难以排错的错误。 然而,为了本例的简化展示,我们暂时搁置这一问题,因为在更复杂的实际应用中,可选用其他方法,例如ES6中的模板字符串或其他函数来安全地构建和执行字符串。 具体到本例的代码实现,`MM_jumpMenu`函数负责处理转向逻辑。 它接收三个参数:`targ`、`selObj`和`restore`。 其中`targ`代表要转向的页面,`selObj`是触发事件的下拉列表框对象,`restore`是标志位,用以指示是否需在转向后将下拉列表框的选项恢复至默认的提示项。 函数的实现通过获取`selObj`中当前选定的`selectedIndex`对应的`value`属性值,并将其赋予`...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值